我想从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]
答案 0 :(得分:2)
有一些很好的方法可以做到这一点。如果您不关心最后一个元素是NaN,则可以使用np.diff
xml.tag!(brand) do
end
结果将具有形状myarr = np.random.rand(20, 7, 11, 151, 161)
newarr = np.diff(myarr, axis=1)
。
如果您真的想保留这些NaN,我建议您使用np.empty_like
和np.subtract
。用np.full
分配有点浪费,因为您肯定要设置几乎所有元素。您唯一的NaN位于第二维的最后一个索引中,您可以自己廉价地进行初始化:
(20, 6, 11, 151, 161)
由于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, ...]
是视图,因此该操作几乎完全避免了临时数组和不必要的初始化。
答案 1 :(得分:1)
数字版本:
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
答案 2 :(得分:0)
只需使用数组切片来获得较小的数组,在数组上添加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个长的一维数组可以很好地证明这一点。
答案 3 :(得分:0)
您可以使用:
选择整个尺寸。
for iwk in range(6):
newarr[:,iwk,:,:,:] = myarr[:,iwk+1,:,:,:] - myarr[:,iwk,:,:,:]