i具有一个3D numpy阵列,带有浮子,如果值小于值(vmin),则需要将每个元素的值替换为邻居(i-1)。实施的代码效率很低:
def replace_values(B,vmin,nt,nx,ny):
# B is a numpy array
# nt, nx ny the dimensions
for z in xrange(0,nt):
print i
for y in xrange(0,ny):
values=B[z,:,y]
if numpy.amin(values)==0:
for x in xrange(1,nx):
if B[z,x,y]<vmin:
B[z,x,y]=B[z,x-1,y]
return B
有什么方法可以实现迭代器以提高速度?
我拥有数组大小的一个限制,几乎是RAM内存的大小,无法完成副本。
看起来您的内部循环在1D视图上工作,因此可以编码为:
In [386]: values=np.random.randint(0,10,20)
In [387]: values
Out[387]: array([1, 5, 9, 4, 6, 7, 1, 5, 6, 4, 4, 3, 9, 5, 8, 5, 0, 3, 1, 2])
In [388]: np.amin?
In [389]: for x in range(1,len(values)):
...: if values[x]<5:
...: values[x]=values[x-1]
...:
In [390]: values
Out[390]: array([1, 5, 9, 9, 6, 7, 7, 5, 6, 6, 6, 6, 9, 5, 8, 5, 5, 5, 5, 5])
如果是这样,一个目标是加快它的速度,可能是使用UFUNC accumulate
功能之一(想想cumsum
的动作)。
下一个问题是,我们可以避免在其他两个维度上进行迭代。有了一些转置和重塑,我们可以将其浓缩到1D的迭代中,但这并不能节省时间。在2D数组上测试想法比3D更容易。
我要建议apply_along_axis
来照顾迭代的详细信息,但它不用,甚至不使用out
参数)。
======================
让我们尝试将此操作应用于2D数组的所有值。
In [398]: val2d=np.array((x1,x1+2, x1-2))
In [399]: val2d
Out[399]:
array([[ 1, 5, 9, 4, 6, 7, 1, 5, 6, 4, 4, 3, 9, 5, 8, 5, 0, 3, 1, 2],
[ 3, 7, 11, 6, 8, 9, 3, 7, 8, 6, 6, 5, 11, 7, 10, 7, 2, 5, 3, 4],
[-1, 3, 7, 2, 4, 5, -1, 3, 4, 2, 2, 1, 7, 3, 6, 3, -2, 1, -1, 0]])
In [400]: for i in range(1,val2d.shape[1]):
...: mask = val2d[:,i]<5
...: val2d[mask,i]=val2d[mask,i-1]
...:
In [401]: val2d
Out[401]:
array([[ 1, 5, 9, 9, 6, 7, 7, 5, 6, 6, 6, 6, 9, 5, 8, 5, 5, 5, 5, 5],
[ 3, 7, 11, 6, 8, 9, 9, 7, 8, 6, 6, 5, 11, 7, 10, 7, 7, 5, 5, 5],
[-1, -1, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, 7, 7, 6, 6, 6, 6, 6, 6]])
然后,此3D版本应起作用(未测试):
for i in range(1, B.shape[1]):
mask = B[:,i,:]<vmin
I,J = np.where(mask)
B[I,i,J] = B[I,i-1,J]
这是使用示例1D
数据以简单方式描述的问题。
假设输入数据数组是:
In [398]: a
Out[398]: array([4, 8, 2, 6, 3])
假设掩码基于要进行的数据是基于哪个数据(填充要在错误的位置上完成):
In [407]: mask
Out[407]: array([ True, True, False, True, False], dtype=bool)
首先,我们创建了一个基于蒙版的索引数组
In [409]: mask*np.arange(mask.size)
Out[409]: array([0, 1, 0, 3, 0])
接下来,我们确实累积了,它向前填充了基于掩蔽的零件数组 -
In [410]: np.maximum.accumulate( mask*np.arange(mask.size) )
Out[410]: array([0, 1, 1, 3, 3])
因此,最后一步是简单地用这些累积索引阵列索引数据数组 -
In [411]: a[np.maximum.accumulate( mask*np.arange(mask.size) )]
Out[411]: array([4, 8, 8, 6, 6])
如果您将其与原始数据阵列进行了比较,我们将其转发在蒙版的False
位置上。
最终实现
让我们将前面列出的基于np.maximum.accumulate
的解决方案扩展到几乎没有索引方法的3D
情况
nt, nx, ny = B.shape
d0,d2 = np.where(B.min(1)==0)
dim2_idx = np.maximum.accumulate( (B[d0,:,d2]>=vmin)*np.arange(nx), axis=1)
B[d0[:,None],np.arange(nx),d2[:,None]] = B[d0[:,None],dim2_idx,d2[:,None]]