Numpy学习笔记
属性
ndim:维度
shape:行数和列数
size:元素个数
创建
array:创建数组
dtype:指定数据类型
zeros:创建数据全为0
ones:创建数据全为1
empty:创建数据接近0
arange:按指定范围创建数据
linspace:创建线段
array
a = np.array([2,23,4]) # list 1d
print(a)
# [2 23 4]
a = np.array([[2,23,4],[2,32,4]]) # 2d 矩阵 2行3列
print(a)
"""
[[ 2 23 4]
[ 2 32 4]]
"""
dtype
a = np.array([2,23,4],dtype=np.int)
print(a.dtype)
# int64
a = np.array([2,23,4],dtype=np.int32)
print(a.dtype)
# int32
a = np.array([2,23,4],dtype=np.float)
print(a.dtype)
# float64
a = np.array([2,23,4],dtype=np.float32)
print(a.dtype)
# float32
zeros
a = np.zeros((3,4)) # 数据全为0,3行4列
"""
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
"""
empty
a = np.empty((3,4)) # 数据为empty,3行4列
"""
array([[ 0.00000000e+000, 4.94065646e-324, 9.88131292e-324,
1.48219694e-323],
[ 1.97626258e-323, 2.47032823e-323, 2.96439388e-323,
3.45845952e-323],
[ 3.95252517e-323, 4.44659081e-323, 4.94065646e-323,
5.43472210e-323]])
"""
arange
a = np.arange(10,20,2) # 10-19 的数据,2步长
"""
array([10, 12, 14, 16, 18])
"""
reshape
a = np.arange(12).reshape((3,4)) # 3行4列,0到11
"""
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
"""
linspace
a = np.linspace(1,10,20) # 开始端1,结束端10,且分割成20个数据,生成线段
"""
array([ 1. , 1.47368421, 1.94736842, 2.42105263,
2.89473684, 3.36842105, 3.84210526, 4.31578947,
4.78947368, 5.26315789, 5.73684211, 6.21052632,
6.68421053, 7.15789474, 7.63157895, 8.10526316,
8.57894737, 9.05263158, 9.52631579, 10. ])
"""
reshape
a = np.linspace(1,10,20).reshape((5,4)) # 更改shape
"""
array([[ 1. , 1.47368421, 1.94736842, 2.42105263],
[ 2.89473684, 3.36842105, 3.84210526, 4.31578947],
[ 4.78947368, 5.26315789, 5.73684211, 6.21052632],
[ 6.68421053, 7.15789474, 7.63157895, 8.10526316],
[ 8.57894737, 9.05263158, 9.52631579, 10. ]])
"""
运算
c=a-b
c=a+b
c=a*b
c=b**2
c=10*np.sin(a)
c_dot = np.dot(a,b)#叉积
np.sum(a)
np.min(a)
np.max(a)
np.sum(a,axis=1)#0行1列
np.min(a,axis=0)
np.max(a,axis=1)
np.argmin(A)#求最小的索引,矩阵转化为一行的坐标
np.argmax(A)
np.mean(A)#平均值
A.mean()
A.median()#中位数
np.cumsum(A)#累加
p.diff(A)#每项与后一项的差(后-前)
np.nonzero(A)#将所有非零元素的行与列坐标分割开,重构成两个分别关于行和列的矩阵。
np.sort(A)#仅针对每一行进行从小到大排序操作:
np.transpose(A)#转置
A.T
np.clip(A,5,9)#将矩阵中元素比最小值小的或者比最大值大的转换为最小值或者最大值。
索引,合并,分割
A[1][1]
print(A[1, 1:3]) #切片
A.flatten()#将矩阵展开为一行
np.vstack((A,B))#将矩阵上下合并
np.hstack((A,B))#将矩阵左右合并
A[np.newaxis,:]#将array转化为矩阵,以便用上面两个函数合并
A[np.newaxis,:]
np.concatenate((A,B,B,A),axis=0)#将多个矩阵合并
np.split(A, 3, axis=0)#矩阵横向平分为3个
np.array_split(A, 3, axis=0)#不均等分割
np.vsplit()
np.hsplit()
浅拷贝与深拷贝
= 的赋值方式会带有关联性
copy() 的赋值方式没有关联性
加速方法
Numpy 快速的矩阵相乘运算, 能将乘法运算分配到计算机中的多个核, 让运算并行. 这年头, 我们什么都想 多线程/ 多进程 (再次说出了机器学习同学们的心声~). 这也是 Numpy 为什么受人喜欢的一个原因. 这种并行运算大大加速了运算速度.
横纵对应
当你的计算中涉及合并矩阵, 不同形式的矩阵创建方式会给你不同的时间效果. 因为在 Numpy 中的矩阵合并等, 都是发生在一维空间里, ! 不是我们想象的二维空间中!
a = np.zeros((200, 200), order='C')
b = np.zeros((200, 200), order='F')
N = 9999
def f1(a):
for _ in range(N):
np.concatenate((a, a), axis=0)
def f2(b):
for _ in range(N):
np.concatenate((b, b), axis=0)
t0 = time.time()
f1(a)
t1 = time.time()
f2(b)
t2 = time.time()
print((t1-t0)/N) # 0.000040
print((t2-t1)/N) # 0.000070
在 Numpy 中, 创建 2D Array 的默认方式是 “C-type” 以 row 为主在内存中排列, 而如果是 “Fortran” 的方式创建的, 就是以 column 为主在内存中排列.
row 为主的存储方式, 如果在 row 的方向上合并矩阵, 将会更快. 因为只要我们将思维放在 1D array 那, 直接再加一个 row 放在1D array 后面就好了, 所以在测试中, f1 速度要更快. 但是在以 column 为主的系统中, 往 1D array 后面加 row 的规则变复杂了, 消耗的时间也变长. 如果以 axis=1 的方式合并, “F” 方式的 f2将会比 “C” 方式的 f1 更好。为了速度, 推荐还是尽量使用 np.concatenate。
copy慢 view快
减少创建无用的变量
用np.ravel()不用np.flatten()
view操作
a_view1 = a[1:2, 3:6] # 切片 slice
a_view2 = a[:100] # 同上
a_view3 = a[::2] # 跳步
a_view4 = a.ravel() # 上面提到了
copy操作
a_copy1 = a[[1,4,6], [2,4,6]] # 用 index 选
a_copy2 = a[[True, True], [False, True]] # 用 mask
a_copy3 = a[[1,2], :] # 虽然 1,2 的确连在一起了, 但是他们确实是 copy
a_copy4 = a[a[1,:] != 0, :] # fancy indexing
a_copy5 = a[np.isnan(a), :] # fancy indexing
使用 np.take(), 替代用 index 选数据的方法.
a = np.random.rand(1000000, 10)
N = 99
indices = np.random.randint(0, 1000000, size=10000)
def f1(a):
for _ in range(N):
_ = np.take(a, indices, axis=0)
def f2(b):
for _ in range(N):
_ = b[indices]
print('%f' % ((t1-t0)/N)) # 0.000393
print('%f' % ((t2-t1)/N)) # 0.000569
使用 np.compress(), 替代用 mask 选数据的方法.
mask = a[:, 0] < 0.5
def f1(a):
for _ in range(N):
_ = np.compress(mask, a, axis=0)
def f2(b):
for _ in range(N):
_ = b[mask]
print('%f' % ((t1-t0)/N)) # 0.028109
print('%f' % ((t2-t1)/N)) # 0.031013
out参数很快
a += 1 # 0.011219
np.add(a, 1, out=a) # 0.008843
带有 out 的 numpy 功能都在这里:Universal functions.
Reference