我想应用一个将2D数组(并返回相同形状之一)的函数应用于3D数组的每个2D切片。这是一种有效的方法吗? numpy.fromiter
会返回一维数组,numpy.fromfunction
需要单独应用于每个坐标。
目前我在做
foo = np.array([func(arg, bar2D) for bar2D in bar3D])
这给了我想要的东西,但列表理解非常慢。此外,func
是具有特定边界条件的一维导数。 numpy.gradient
似乎只做N-D导数,N是数组的维度,但也许还有另一个例程可以为我做整件事?
编辑:列表理解有效,但我正在寻找更快的方法。 bar3D
可能很大,最高可达(500,500,1000)
。我发现的将函数应用于数组的所有numpy
例程似乎都假定函数或数组都是1D。
答案 0 :(得分:1)
我不知道将函数应用于N-D数组切片的任何通用方法。但有两种方法可以解决它。
如果你想要做的是在每个2D切片的每一行或每列上应用一维导数,这相当于将导数应用于每个一维切片,你可以使用np.apply_along_axis:
values = np.arange(4)*np.arange(3)[:, None]+np.arange(2)[:, None, None]*2
>>> array([[[0, 0, 0, 0],
[0, 1, 2, 3],
[0, 2, 4, 6]],
[[2, 2, 2, 2],
[2, 3, 4, 5],
[2, 4, 6, 8]]])
np.apply_along_axis(np.gradient, 2, values)
>>> array([[[ 0., 0., 0., 0.],
[ 1., 1., 1., 1.],
[ 2., 2., 2., 2.]],
[[ 0., 0., 0., 0.],
[ 1., 1., 1., 1.],
[ 2., 2., 2., 2.]]])
这可以区分每个2D切片的行。要对每列进行区分,请执行np.apply_along_axis(np.gradient, 2, values)
如果你想做一些需要两个维度的事情,你通常可以通过广播和轴参数来获得它。例如,如果您希望每个切片V[i, j] = sqrt((V[i,j]-V[i, j-1])^2+V[i, j]-V[i-1, j])^2
都V
,则可以执行以下操作:
xdiffs = np.zeros_like(values)
xdiffs[:, 1:, :]= np.diff(values, axis=1)
ydiffs = np.zeros_like(values)
ydiffs[:, :, 1:] = np.diff(values, axis=2)
diffnorms = np.linalg.norm(xdiffs, ydiffs)
>>> array(
[[[ 0. , 0. , 0. , 0. ],
[ 0. , 1.41421356, 2.23606798, 3.16227766],
[ 0. , 2.23606798, 2.82842712, 3.60555128]],
[[ 0. , 0. , 0. , 0. ],
[ 0. , 1.41421356, 2.23606798, 3.16227766],
[ 0. , 2.23606798, 2.82842712, 3.60555128]]])
获得正确的尺寸有点麻烦,但它通常是最有效的解决方案。
此示例在边界使用零,如果您还需要其他内容,则需要将normdiff[:, :, 0]
和normdiff[:, 0, :]
设置为正确的边界值。
答案 1 :(得分:-2)
假设你有一个数组,a:
>>> a=np.random.random((4,3,2))
array([[[ 0.27252091, 0.78545835],
[ 0.83604934, 0.48509821],
[ 0.77828735, 0.26630055]],
[[ 0.98623474, 0.29839813],
[ 0.15893604, 0.61870988],
[ 0.62281607, 0.27193647]],
[[ 0.47976331, 0.2471835 ],
[ 0.77323041, 0.30137068],
[ 0.52906156, 0.53950597]],
[[ 0.59207654, 0.86355457],
[ 0.50250812, 0.75688653],
[ 0.91046136, 0.5785383 ]]])
您可以像这样访问2D切片:
>>> for x in range(a.shape[0]):
print a[x,:,:]
>>> for x in range(a.shape[1]):
print a[:,x,:]
>>> for x in range(a.shape[2]):
print a[:,:,x]