我想从numpy数组中减去特定轴中当前元素的下一个元素。但是,我知道如何使用大量循环来做到这一点。我的问题是:如何以最有效的方式做到这一点?也许使用numpy?
我的Python代码如下:
import numpy as np
np.random.seed(0)
myarr = np.random.rand(20, 7, 11, 151, 161)
newarr = np.full((20, 6, 11, 151, 161), np.nan)
for iyr in range(20):
for iwk in range(6):
for imb in range(11):
for ilat in range(151):
for ilon in range(161):
newarr[iyr, iwk, imb, ilat, ilon] = myarr[iyr, iwk + 1, imb, ilat, ilon] - myarr[iyr, iwk, imb, ilat, ilon]
有一些很好的方法可以做到这一点。如果你不关心最后一个元素是NaN,你可以使用np.diff
myarr = np.random.rand(20, 7, 11, 151, 161)
newarr = np.diff(myarr, axis=1)
结果将有形状(20, 6, 11, 151, 161)
。
如果你真的想保留那些NaN,我建议使用np.empty_like
和np.subtract
。与np.full
分配有点浪费,因为你肯定设置几乎所有的元素。您拥有的唯一NaN位于第二维的最后一个索引中,您可以自己非常便宜地初始化:
myarr = np.random.rand(20, 7, 11, 151, 161)
newarr = np.empty_like(myarr) # Don't repeat shape
newarr[:, -1, ...] = np.nan
np.subtract(myarr[:, 1:, ...], myarr[:, :-1, ...], out=newarr[:, :-1, ...])
由于myarr[:, 1:, ...]
,myarr[:, :-1, ...]
和newarr[:, :-1, ...]
是视图,因此该操作几乎完全避免了临时数组和不必要的初始化。
Numpy版本:
myarr = np.random.rand(20, 7, 11, 151, 161)
newarr_np = myarr[:, 1:,] - myarr[:, :-1]
您编辑的代码:
from itertools import product
newarr = np.full((20, 6, 11, 151, 161), np.nan)
for iyr, iwk, imb, ilat, ilon in product(range(20), range(6), range(11), range(151), range(161)):
newarr[iyr, iwk, imb, ilat, ilon] = \
myarr[iyr, iwk + 1, imb, ilat, ilon] - \
myarr[iyr, iwk , imb, ilat, ilon]
平等测试
np.all(newarr_np == newarr)
> True
您可以使用:
选择整个尺寸。
for iwk in range(6):
newarr[:,iwk,:,:,:] = myarr[:,iwk+1,:,:,:] - myarr[:,iwk,:,:,:]
只需使用数组切片来获得较小的一个,向其中添加0行/列以将其扩展为相同的大小,然后减去。像这样:
>>> x=np.random.rand(10)
>>> x #this is our original array
array([0.49662379, 0.18424862, 0.43346481, 0.57377969, 0.88027509,
0.9820584 , 0.63669062, 0.27981557, 0.70115255, 0.47660883])
>>> x[1:] #this is the one we want to subtract, but to do that, you need to pad it with zeros
array([0.18424862, 0.43346481, 0.57377969, 0.88027509, 0.9820584 ,
0.63669062, 0.27981557, 0.70115255, 0.47660883])
>>> ext=np.zeros(1) # so we take a few zeros
>>> ext
array([0.])
>>> np.concatenate((x[1:],ext)) # pad it
array([0.18424862, 0.43346481, 0.57377969, 0.88027509, 0.9820584 ,
0.63669062, 0.27981557, 0.70115255, 0.47660883, 0. ])
>>> x-np.concatenate((x[1:],ext)) # and subtract
array([ 0.31237516, -0.24921618, -0.14031489, -0.3064954 , -0.10178331,
0.34536778, 0.35687505, -0.42133698, 0.22454372, 0.47660883])
当然可以有更简单的解决方案。您可以选择不同的尺寸,但10长1D阵列可以很好地证明这一点。