在三维numpy数组中扩展内部数组



我有两个numpy数组,形状类似于:

A = (2000, 2000, 3)B = (2000, 2000, 4)

我还有一组索引,比如[1,3]

我需要做的是获取两个原始数组,并创建一个新数组(2000, 2000, 5),其中每个内部数组都是a的内部数组的全部内容,以及B的指定索引。

所以内部数组可能是:

(A[0], A[1], A[2], B[1], B[3])

我目前正在Python中直接执行此操作,如下所示:

width = 2000
height = 2000
out_data = np.empty((height, width, 5), np.float32)
for y in range(height):
for x in range(width):
out_data[y][x][:3] = A[y][x]
out_data[y][x][3] = B[y][x][1]
out_data[y][x][4] = B[y][x][3]

这很慢。我想知道的是,是否有更好的方法可以在numpy中做到这一点?

如果有一种方法可以通过扩展A来实现这一点,我很高兴,因为AB仅用于此目的。

ix = [1, 3]
new = np.c_[A, B[:, :, ix]]

最小示例

width = 5
height = 5
A = np.arange(np.prod((width, height, 3))).reshape(width, height,3)
B = -np.arange(np.prod((width, height, 4))).reshape(width, height,4)

OP代码:

ix = [1, 3]  # or (1, 3)
out_data = np.empty((height, width, 5), A.dtype)
for y in range(height):
for x in range(width):
out_data[y][x][:3] = A[y][x]
out_data[y][x][3] = B[y][x][1]
out_data[y][x][4] = B[y][x][3]

此解决方案:

new = np.c_[A, B[:, :, ix]]
>>> np.array_equal(out_data, new)
True

速度

width = 2000
height = 2000
# ...
# time of OP's: 9.55s
%timeit np.c_[A, B[:, :, ix]]
# 143 ms ± 42.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

您可以沿着最后一个轴排列dstack

out_data = np.dstack([A, B[:,:,[1,3]]])

您应该能够像这样使用np.concatenate作为示例。

np.concatenate((a, b[:,:,(1,3)]), axis=2)

在2000x2000个数组作为输入时,它的运行速度大约是原始代码的61倍,大致等于直接索引。

以下内容以矢量化的方式与您的代码相同,没有for循环:

out = np.empty((2000, 2000, 5))
out[:, :, :3] = A
out[:, :, 3:5] = B[:, :, [1,3]]

最新更新