RQL's Blog 菜鸟成长记

numpy用法

2022-06-25
renql

numpy主要用于数组与矩阵运算,主要数据结构就是N维同类型数组array,可以用array.shape, array.dtype查看数组结构和类型

创建数组

a = np.array([1,2,3],dtype=float)   
b = np.zeros(a.shape)  
c = np.zeros( [len(lev),len(behv),len(months),len(year)],dtype=float )
x = np.arange(6).reshape(2,3) + 10
# 得到数组 array([[10, 11, 12],[13, 14, 15]])


ind = np.argwhere(x>11)
# 得到一个二维数组,表示满足条件的位置坐标
# array([[0, 2],[1, 0],[1, 1],[1, 2]])
# 此时 x[ind[:,0],ind[:,1]] 为 array([12, 13, 14, 15])


ind = np.unravel_index(np.argmax(x, axis=None), x.shape)
# 得到的ind 为(1,2), x[ind] = 15
# 若直接 np.argmax(x, axis=None),得到的结果是5
# 若 np.argmax(x, axis=0),得到的结果 array([1, 1, 1])

数学运算

两个不同维度的数组(a/b)相除,只有当b的维数与a的最后几个维数相等时才可以相除

a=np.arange(24).reshape((4, 3, 2))
b=np.arange(6).reshape((3, 2))
print(a/b) 
#array([[[ nan,  1. ],[ 1. ,  1. ],[ 1. ,  1. ]],
#       [[ inf,  7. ],[ 4. ,  3. ],[ 2.5,  2.2]],
#       [[ inf, 13. ],[ 7. ,  5. ],[ 4. ,  3.4]],
#       [[ inf, 19. ],[10. ,  7. ],[ 5.5,  4.6]]])
#

b=np.array([1,2,3,4])
c=a/b # 报错
# ValueError: operands could not be broadcast together with shapes (4,3,2) (4,)

# 此时可以将a中的第一维度移动到最后,这样就可以和b相除
c = np.moveaxis(a,0,-1)/b # c.shape 等于 (3, 2, 4)
d = np.moveaxis(c,-1,0)   # d.shape 等于 (4, 3, 2)

# 也可以将b变成和a一样维数的数组,然后再相除,得到的结果一样
d = a/np.broadcast_to(b.reshape(4, 1, 1), a.shape)

逻辑运算

a=np.array([tim3.time.dt.year.isin(1990),tim3.time.dt.month.isin(2)])
print(a)
print(a.all(axis=0))
# output:
#[[ True  True False]
# [False  True False]]
#
#[False  True False]


new = np.where(a<5, a, 10*a)
# 原数组为 array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 新数组为 array([0, 1, 2, 3, 4, 50, 60, 70, 80, 90])])

a = xr.DataArray(np.arange(25).reshape(5, 5), dims=("x", "y"))
new = xr.where(a<5, a, 10*a) # 用法通np.where

# 但 xarray.DataArray.where 的用法和 xr.where 不同
a.where(a.x + a.y < 5, -1) # 将不满足条件的值设为-1,若不给定,则会设为缺测
a.where(a.x + a.y < 5, drop=True) # 将不满足条件的值设为缺测,并删去都是缺测的列或行
# a.x + a.y < 5返回逻辑数组,因此也可以用 a.x.isin([2,3]) 代替

# numpy 也有 isin的用法,但格式和 xarray 不一样
b = np.array([range(5,15,1),range(0,10,1)])
mask = np.isin(b, range(5,10))
# mask是一个shape同b的逻辑数组,
# b[mask]可以得到 array([5, 6, 7, 8, 9, 5, 6, 7, 8, 9])
mask_invert = np.isin(b, range(5,10), invert=True)
# mask_invert是mask的逻辑反面,即mask为True的地方,mask_invert为False

numpy的文本文件操作

numpy.savetxt(fname,X,fmt='%.18e')
# 第一个参数为文件名,第二个参数为需要存的数组(一维或者二维)
# 数组的第一个维度变为行,第二个维度变为列
# 这个写入功能用得比较少,感觉没有python自带的写入功能好用
# 详情可参考 https://renqlsysu.github.io/2021/10/04/python_file/

data = numpy.loadtxt(fname,dtype=<class 'float'>, 
	comments='#', delimiter=None, usecols = (0,1))
# 将数据读出为array类型,若文件有ny行,nx列,得到的数组维度是(ny,nx)
# 可以用skiprows跳过前几行,用usecols指定读取的列(从0列开始)

支持 支付宝鼓励 鸡腿鸡腿

喜欢此文!

Similar Posts