生成
lst = [[1.0, -2], [-3, 4]]
x = np.array(lst, dtype=float)
# dtype=float, int, np.complex128
np.array(lst, ndmin=3) # shape = (1, 2, 2)
y = array(lst, ndmin=4) # shape = (1, 1, 2, 2)
np.zeros(shape=(5, 2), dtype=int)
# 含头不含尾:
np.arange(start=0, stop=11, step=1)
# 含头含尾:
np.linspace(start=0, stop=5, num=9)
np.eye # 对角矩阵
np.random.rand(2, 2, 2) # 2x2x2 的随机矩阵
# 占用 bytes
z.size * z.itemsize
取数
- 切片取数:共享内存(对于多维数组,如果每一维都用切片,也共享内存)
a[3:5] # 含头不含尾 a[:-1] # -1表示最后,仍然不含尾 a[2, 3] = 7, 8 # 切片用来改array b = a[2, 3] # a和b共享内存空间 a[1:-1:2] # 最后一个数是步长 a[::2] # 省略表示头部
- 用list取数:不共享内存(对于多维数组,可以用切片+list混用方式取数,只要有list就不共享内存)
a=np.arange(1,10,1) b=a[[1,2,3]] # 修改b的元素值,不影响a
- array取数:不共享内存
a=np.arange(1,10,1) b=a[np.array([1,4,1])]
- 布尔取数:不共享内存
a=np.arange(0,5,1) b=a[np.array([True,False,True,False,True])]
一个实际案例:
a=numpy.random.rand(10)
a[a>0.5]
摊平操作
index 相关
# 6x7x8 矩阵的第 100 个元素,其 index 是什么
np.unravel_index(indices=100, shape=(6, 7, 8)) # 返回 (1, 5, 4)
# 6x7x8 矩阵,其坐标 (1, 5, 4) 的元素,是第几个元素
np.ravel_multi_index(multi_index=(1, 5, 4), dims=(6, 7, 8)) # 返回 100
# 以上方法也可以输入多组值,同时计算和返回
# 例如:
x_arr, y_arr = np.unravel_index(indices=[1, 2, 3], shape=(3, 3))
# 返回 (array([0, 0, 1]), array([1, 2, 0]))
# (0, 0) 和 (1, 2) 对应第几个?
np.ravel_multi_index(multi_index=[(0, 1), (0, 2)], dims=(3, 3))
# 返回 array([0, 5])
# 摊平
x.flatten()
# 取摊平后的第 6 个元素
x.item(6)
习题:有一个5x5的零矩阵,使随机n个元素变成1
x = np.zeros((5, 5))
n = 3
idx = np.random.choice(a=range(x.size), size=n, replace=False)
idx2 = np.unravel_index(indices=idx, shape=x.shape)
x[idx2] = 1
方法
a.shape
- 返回a的维度
- 如果a是一维数组,输出为(4,)
- 二维数组,输出为(2, 1)
- 如果某一维不规则,那么不显示这一维(2,)
a.shape返回array的维度
a.shape
- 可以对a.shape赋值,效果是改变维度
a=numpy.array([[1,2,3],[4,5,6]]) a.shape=3,2
- 在赋值时,用-1表示自动计算这一维的长度
a=numpy.array([[1,2,3],[4,5,6]]) a.shape=3,-1
reshape
- reshape与shape的区别是,reshape保持原数组维度不变
- 相同点是,内存是共享的
a=numpy.array([[1,2,3],[4,5,6]])
b=a.reshape((3,2))
这里生成的a和b维度不同,但是共享内存
比较而言,用shape,直接改了原array:
a=numpy.array([[1,2,3],[4,5,6]])
b=a
b.shape=3,-1
b.shape=6 # 变成一维的
这里a,b的维度都改了
dtype
a.dtype#返回元素类型
a=numpy.array([1,2,3,4],dtype=numpy.float)#指定元素类型
a=numpy.array([1,2,3,4],dtype=numpy.complex)#指定元素类型
显示可用的dtype列表
set(numpy.typeDict.values())
np.pad:四周添加数字
np.pad(array, pad_width, mode='constant')
- pad_width:
((before_1, after_1), ... (before_N, after_N))
,例如((2, 3), (4, 5))
表示第1纬度前填充2后填充3,第2纬度前填充4后填充5 - mode
- ‘constant’ (default) 常量填充。默认填0,配合
constant_values=((-10, 10), (-20, 20))
指定填充什么数字。上面是第1个纬度前后填充-10和10,第二个纬度前后填充-20,20 - ‘edge’ 用边缘填充
- 还有很多填充模式,用的时候查
- ‘constant’ (default) 常量填充。默认填0,配合
where
x = np.array([1, 2, 0, 0, 3, 2, 0])
np.where(x != 0) # 返回符合条件的 index
np.where(x != 0, 9, 99) # 符合条件则填充为 9,否则填充为 99
统计方法
以下方法都可以
- 对数组操作。
- 加nan表示跳过nan,例如
nanmean
方法 | 说明 |
---|---|
sum | |
mean | |
std,var | |
min,max | |
argmin,argmax | 最小值和最大值的索引 |
cumsum | |
cumprod | |
diff | |
sort | 排序 |
使用详解
# 对 ndarray 的操作
arr1 = np.random.rand(5, 3)
np.mean(arr1)
np.mean(arr1, axis=1, keepdims=True)
# 1. 对第axis维度求平均
# 2. keepdims 默认为 False,表示把结果变成一维的
# 加nan表示跳过nan
np.nanmean(arr1)
其它统计学方法
# 协方差矩阵
np.corrcoef(arr1)
常用方法
np.ceil
np.floor
np.rint
np.isnan
np.unique # 去重并排序
np.unique(
arr
, return_index=True # 额外返回一个array,记录去重后的元素来自 arr 的哪个位置
, return_inverse=True # 额外返回一个array,用它+返回值可以重新构建 arr
, return_counts=True # 额外返回一个array,记录元素个数
, axis=0 # 按照axis去重;如果没有,去重粒度是元素,
)
集合
np.intersect1d([1, 2, 3], [4, 3, 5]) # 交集
np.union1d([1, 5, 4], [5, 3, 1]) # 并集
np.in1d(ar1=[1, 4, 4, 1, 2], ar2=[1, 2]) # ar1 中每个元素,是否是 ar2 中的元素。返回一个 np.array<bool> ,大小与 ar1 一致
逻辑运算
np.logical_not([True, True, False]) # 求否
np.logical_or(arr1, arr2)
np.logical_and(arr1, arr2)
# 更好记:
arr1 & arr2
arr1 | arr2
~arr1
np.all
np.any
np.isnan(np.array([1, np.nan]))
sort
import numpy as np
a=np.random.randn(10,3)
a.sort(axis=1) # 直接改变a
np.sort(a) # 不改变a,而是返回一个排序完毕的ndarray
- axis=1,axis=1是对行降序,axis=0是对列降序
- 只能降序排列,向生序
a[:,::-1]
kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}
np.argsort
np.meshgrid
X, Y = np.meshgrid(np.arange(3), np.arange(4))
矩阵操作
常用方法
a=np.random.rand(3,4)
np.fliplr(a) # 左右翻转
np.flipud(a) # 上下翻转
np.rot90(a,k=3) # 逆时针转动k次
np.eye(N=4,M=3,k=2) # 生成一个对角阵,N*M大小,k是向右上角偏置量
np.diag(a,k=1) # 取出对角元素,放到一维数组中,返回一个 1darray
np.diag([1,2,3],k=2) # 生成对角矩阵(一维数组转二维数组)
# np.diag 没有 keepdim 这类入参,可以用 np.diag(np.diag(a)) 来提取对角矩阵
np.triu(m=a,1) # 矩阵的上三角部分
np.tril(m=a,1) # 矩阵的下三角部分
np.tri(N=3,M=4,k=1) # 生成一个下三角矩阵,元素是0和1
np.vander(x=[1,2,3],N=5) # 生成一个 Vandermonde matrix,每一行是x中的元素,N列
(a>0.5).any(axis=0) # 每列是否有True
(a>0.5).any(axis=1) # 每行是否有True
np.tile(np.array([[1, 2], [3, 4]]), (3, 2))
# 把一个矩阵复制 3*2 次,也就是行变成 3 倍,列变成 2 倍
矩阵拆拼
拼装
import numpy as np
a=np.random.rand(3,3)
b=np.random.rand(3,3)
np.concatenate([a,b],axis=0) # axis=0是竖着拼起来,axis=1是横着拼起来
scipy距离矩阵
https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.cdist.html#scipy.spatial.distance.cdist
import numpy as np
from scipy import spatial
num_points = 8
points = range(num_points) # generate index of points
points_coordinate = np.random.rand(num_points, 2) # generate coordinate of points
distance_matrix = spatial.distance.cdist(points_coordinate, points_coordinate, metric='euclidean')
存文件和读文件
文本类型的存和读
# 以下两个方法可以读 csv/txt 等格式
arr1 = np.genfromtxt('file1.csv', delimiter=',')
# 如果某个数据是字符串,相应位置会读取为nan
arr2 = np.loadtxt('file1.csv', delimiter=',', skiprows=1)
# 多了一个 skiprows 方法,一般用来跳过第一行(字段名)
# 如果某个数据是字符串,会报错
二进制形式存和读(*.npy
格式)
# 存
np.save('file4.npy', arr1)
# 读
np.load('file4.npy')
多个变量批量存/读(*.npz
格式)
# 存
# 区别是:是否压缩
np.savez('file2.npz', arr1=arr1, arr2=arr2)
np.savez_compressed('file2_compressed', arr1=arr1, arr2=arr2)
# 如果不指定变量名,变量值默认为 arr_1, arr_2 等
# 读
npzfile = np.load('file2.npz')
npzfile.files # 一个列表,都有哪些变量名
npzfile['arr2'] # arr2 这个变量的值
npzfile.get(key='arr3', default=1) # 同上,但是对于不存在的变量,返回一个默认值
npzfile.items() # 一个 iterator,key-value 结构
npzfile.values() # 一个 iterator,存放value
scipy 也可以读写文件(据说与Matlab通用)
scipy.io.savemat('file2_scipy', {'arr1': arr1, 'arr2': arr2})
data_scipy = scipy.io.loadmat('file2_scipy')
其它
np.einsum 比较复杂,但是据说效率较低,暂时不写了