(Data analysis part) study note of python NumPy module
本文是我在学习期间的笔记,看的书是《Python数据分析基础教程 NumPy学习指南 》第二版。
Table of Contents
numypy
numpy数组在数值运算方面的效率优于python提供的list容器。
向量加法
-
TypeError: ‘range’ object does not support item assignment ```python def python_sum(n): a = list(range(n)) b = list(range(n)) c = []
for i in range(len(a)): a[i] = pow(i,2) b[i] = pow(i,3) c.append(a[i] + b[i])
return c
def numpy_sum(n): import numpy as np a = pow(np.arange(n), 2) b = pow(np.arange(n), 3) c = a + b
return c
def test(size):
size = int(sys.argv[1])
size = 1000
from datetime import datetime
import sys
start = datetime.now()
c = python_sum(size)
delta = datetime.now() - start
print("The last 2 elements of the sum: ", c[-2:])
print("PythonSum elapsed time in microseconds: ", delta.microseconds)
start = datetime.now()
c = numpy_sum(size)
delta = datetime.now() - start
print("The last 2 elements of the sum: ", c[-2:])
print("NumPySum elapsed time in microseconds: ", delta.microseconds)
test(100000)
两者的输出形式上有差异:numpysum 的输出不包含逗号,numpy的数组对象以专门的数据结构来存储数值。
<a id="orgcf5a345"></a>
## NumPy 基础
<a id="org3635a5c"></a>
### 数组对象
- ndarray 是一个多维数组对象由:实际的数据,描述这些数据的元数据构成。
大部分操作仅仅修改元数据,而不改变底层的实际数据。
- numpy 数组的下标也是从0开始的。
```python
from numpy import *
a = arange(50)
print(a.dtype)
print(a.shape) # 返回一个表示数组维度的tuple
# 创建多维数组
b = array([arange(5), arange(5)])
print(b,"\n",b.dtype,"维度: ",b.shape)
print("选取[1,2]: \n\t", b[1,2])
指定类型
arange(8,dtype = float64)
- 复数是不能转换为整数的。 否则会触发 TypeError
- 数据类型对象是numpy.dtype类的实例。
- 数据类型对象是可以给出单个数组元素在内存中占用的字节数,即dtype类的itemsize属性:
array(6).dtype.itemsize
自定义数据类型
数组的切片和索引
改变数组的维度
先定义一个数组
a = arange(24).reshape(2,3,4)
a
- ravel() 函数完成展平操作,只返回数组的视图。
a.ravel()
- flatten() 展平,会请求分配内存来保存结果。
a.flatten()
- 两个函数都不改变原数组
a
- 用元祖设置维度
a.shape = (6,4) a
- transpose() 得到转置矩阵
a.transpose()
- resize() 和reshape()函数功能一样,但resize会直接修改原来的数组
a.resize(2,12) a
数组的组合
- 先创建一个数组
from numpy import * a = arange(9).reshape(3,3) b = a * 2 print("a = \n",a,"\nb = \n",b)
- hstack((a,b)) 水平组合
hstack((a,b))
- concatenate((a,b),axis = 1) 实现水平组合
concatenate((a,b), axis=1)
- vstack((a,b)) 垂直组合,同样需要构造一个元组作为参数
vstack((a,b))
- concatenate((a,b),axis=0) 实现垂直组合
concatenate((a,b),axis=0)
- dstack((a,b)) 深度组合,将一系列数组沿着纵轴方向进行层叠组合
dstack((a,b))
- columnstack() 对于一位数组将安照列方向进行组合
- == 运算符可以来比较两个 NumPy 数组
column_stack((a, b)) == hstack((a, b))
- rowstack((a,b)) 按行方向进行组合的函数
row_stack((a, b)) == vstack((a, b))
数组的分割
- 水平分割
- hsplit(a,3)
hsplit(a,3)
- split(a,3,axis=1))
split(a,3,axis=1)
- 垂直分割
- vsplit(a,3)
vsplit(a,3)
- split(a,3,axis=0)
split(a,3,axis=0)
- 深度分割
- dsplit(a,3)
c = arange(27).reshape(3,3,3) print("c = \n", c) print("\ndsplit = ",dsplit(c,3))
数组的属性
除了shape和dtype属性外,ndarray对象还有其他许多属性。
- ndim
- 给出数组的维度
b.ndim
- size
- 给出数组元素的总个数
b.size
- itemsize
- 给出数组中元素的被内存中所占的字节数
b.itemsize
- nbytes
- 整个数组所占的存储空间
b.nbytes
- T
b.T
- real,imag
c = array([1.j + 1, 2j + 3]) print("c.real = ",c.real, "\n,c.imag = ",c.imag)
- flat
- T
- 返回一个Numpy.flatiter对像,
- 这是获得flatiter对象的唯一方式,
- 我们无法访问flaiter的构造函数。
- 遍历数组
f = b.flat for i in f: print(i)
- 获取对象
- flat属性是一个可赋值的属性,对flat属性赋值将导致整个数组的元素都被覆盖。
b = arange(4).reshape(2, 2) print("b = ",b) print("b.flat[2] = ",b.flat[2]) print("b.flat[[1,3]] = ",b.flat[[1,3]]) b.flat = 7 print("b = ",b) b.flat[[1,3]] = 1 print("b = ", b)
数组的转换
- tolist()
- 转换成列表
c = array([ 1 + 1.j, 3. + 2.j]) c.tolist()
- astype()
- 转换数组时指定数据类型
- 在复数转换为整数的过程中,丢失了虚部,会报错
print("c = ",c) print("c.astype(int) = ", c.astype(int)) print("c.astype('complex') = ", c.astype('complex'))
常用函数
文件读写
- np.eye(n) 创建单位矩阵
- np.savetxt() 将数据存储到文件中 ```python import os import numpy as np
i2 = np.eye(2) print(‘i2 = ‘,i2) np.savetxt(‘eye2.txt’,i2) print(os.path.exists(‘eye2.txt’))
- loadtxt() 能方便的读取CSV文件
<a id="org5958fea"></a>
## 便捷函数
<a id="org031867e"></a>
## 矩阵和通用函数
- 通用函数 universal functions 即 ufuncs
- 矩阵是ndarray的子类,可以由专门的字符串格式来创建。
- 二维的
- mat, matrix, bmat 函数来创建矩阵
<a id="org018c165"></a>
### 矩阵
1. 创建矩阵
- 用字符串创建
```python
from numpy import *
A = mat('1 2 3; 4 5 6; 7 8 9')
print("Creating from string: ", A)
- 用numpy数组进行创建
mat(arange(9).reshape(3,3))
- 获取转置矩阵
A.T
- 获取逆矩阵
A.I
- 获取转置矩阵
从已有矩阵创建新矩阵
- bmat 即分块矩阵 block matrix
import numpy as np A = np.eye(2) print("A",A) B = 2 * A print("B", B)
- 使用字符串创建复合矩阵
np.bmat("A B; A B")
通用函数
- 通用函数的输入是一组标量,输出也是一组标量。通常可以对应与基本数学运算。
- zeroslike(a) 创建一个和a形状相同的,并且元素个数全部为0的数组。
-
frompyfunc(func,1,1) 创建通用函数,指定输入参数的个数为1,输出参数的个数为1。 ```python def ultimate_answer(a): result = np.zeros_like(a) result.flat = 42
return result
ufunc = np.frompyfunc(ultimate_answer, 1, 1) print(“The answer : “, ufunc(np.arange(4)))
print(“The answer : “, ufunc(np.arange(4).reshape(2,2)))
1. 通用函数的方法
- 通用函数并非真的函数,而是能表示函数的对象
- 通用函数有四个方法,对应两个输入参数,输出一个参数的ufunc对象有效。
- 不符合条件时将报出ValueError异常。
1. reduce
- 在连续的数组元素之间递归调用通用函数,即可得到输入数组的规约(reduce)计算结果
```python
a = np.arange(9)
print("Reduce",np.add.reduce(a))
- accumulate
- 递归作用于输入数组,但它存储中间结果并返回。
np.add.accumulate(a)
- reduceat
- 该函数需要一个数组和一个索引值列表作为参数
print("Reduceat", np.add.reduceat(a, [0, 5, 2, 7])) # 相当于 print("Reduceat step I", np.add.reduce(a[0:5])) print("Reduceat step II", a[5]) print("Reduceat step III", np.add.reduce(a[2:7])) print("Reduceat step IV", np.add.reduce(a[7:]))
- outer
- 该方法返回一个数组,它的秩(rank)等于两个输入数组的秩值之和。
np.add.outer(np.arange(3), a)
算术运算
- 在numpy中,基本的算术运算符+,-和*隐式关连这通用函数add,subtract,和multiply。
- 除法涉及到三个通用函数,divide, truedivide,和 floordivide,以及两个对应的运算符/和//。
- divide, truedivide, floordivide
- floordivide() 函数在整数和浮点数的除法中只保留整数部分。 ```python import numpy as np a = np.array([2,3,4]) b = np.array([1,2,3]) print(“Divide”,np.divide(a,b),”\n”,np.divide(b,a)) print(“True Divide”,np.true_divide(a,b),”\n”,np.true_divide(b,a)) print(“Floor Divide”,np.floor_divide(a,b),”\n”,np.floor_divide(b,a))
print(“/ operator”, a/b,”\n”,b/a) print(“// operator”, a//b, “\n”, b//a)
<a id="org3e6d5a5"></a>
### 模运算
- 计算模数或者余数
- 可用的函数有 mod, remainder, fmod.
- 或者%运算符
1. remainder
- 返回两个数组中元素相除后的余数,如果第二个数字为0, 则直接返回0。
```python
a = np.arange(-4,4)
print("a = ",a)
print("Remainder",np.remainder(a,2))
- mod
- 与 remainder 函数的功能完全一致
np.mod(a,2)
- %
- 该操作符仅仅是 remainder 函数的缩写
a % 2
- fmod
- 所得的余数的正负由被除数决定,与除数的正负无关。
np.fmod(a,2)