如何快速(矢量化?)从一个 numpy 一维数组中提取不同长度的切片并插入到二维数组中

问题描述 投票:0回答:1

我正在尝试将单个 1D numpy 数组中的多个不重叠的切片提取到 2D 数组的连续行中。

假设源数组是,

s=array([0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12])

目标数组是一个由零组成的二维数组,例如,

t = array([[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0]])

我想从

[1:4:1]
中提取切片
[6:10:1]
s
并将它们注入到
t
中。
s
中的切片数量与
t
中的行数一样多。所有切片都比
t
的行长短。每个提取的切片应替换
t
中相应行的值。

t
的期望结果是:

array([[1, 2, 3, 0, 0],
       [6, 7, 8, 9, 0]])

如果提取的切片的长度都相等,那么我可以使用 2D 索引数组来完成此操作,但它们不是。

我怀疑我应该能够通过创建两个切片数组来做到这一点。其中一个定义从源中选择数据的切片,另一个确定目标行位置,然后使用类似的内容,

b[:,target_slice_array]=a[source_slice_array]  

但我就是想不出任何有效的语法。

这是我目前正在使用的简单循环方法。这就是我正在努力加快的速度。

source=np.array([0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12])
source_slices=[np.s_[0:2:1], np.s_[7:10:1]]
target_slices=[np.s_[0:2:1], np.s_[0:3:1]]

target=np.zeros(shape=(2,10), dtype=np.int32)

#for index, (source_slice, target_slice) in enumerate(zip(source_slices, target_slices)):
    #target[index,target_slice]=source[source_slice]

# Doubles the speed by moving the for loop to use range 
for index in range(len(source_slices)):
   target[index,target_slices[index] = source[source_slices[index]]

这会将目标更新为,

[[ 0  1  0  0  0  0  0  0  0  0] 
 [ 7  9 10  0  0  0  0  0  0  0]]
python numpy slice
1个回答
0
投票

以下内容不是很好,而且几乎肯定比小输入的速度慢,但它是完全矢量化的,如果满足以下条件,可能值得这样做:

  • 源索引和目标掩码一次形成,源数据变化;和/或
  • 尺寸巨大。

在所有情况下,您都需要使用真实的数据进行基准测试。

import numpy as np

source = np.arange(13)
source_start = np.array((0, 7, 3))
source_stop = np.array((2, 10, 10))
lengths = source_stop - source_start
target_start = np.array((0, 5, 2))
target_stop = target_start + lengths
target_width = 10

to_repeat = source_start.copy()
to_repeat[1:] -= lengths[:-1].cumsum()
idx = to_repeat.repeat(lengths)
idx += np.arange(idx.size)

target = np.zeros(shape=(source_start.size, target_width), dtype=source.dtype)
x = np.arange(target_width)
target_mask = (x >= target_start[:, np.newaxis]) & (x < target_stop[:, np.newaxis])

target[target_mask] = source[idx]
print(target)
[[0 1 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 7 8 9 0 0]
 [0 0 3 4 5 6 7 8 9 0]]
© www.soinside.com 2019 - 2024. All rights reserved.