与 numpy repeat 一起使用的两个数组的逐元素编织

Element-wise weave of two arrays used with numpy repeat

我有两个长度不等的数组 val1val2 我试图以特定的方式编织在一起等长数组 mult1mult2。一般来说,我的数组很长(~1e6 个元素),这是我计算中的性能关键瓶颈,所以我无法承受 python-for 循环,所以我试图利用Numpy 中的向量化函数。为了明确起见:

mult1 = np.array([0, 1, 2, 1, 0])
mult2 = np.array([1, 0, 1, 1, 0])

val1 = np.array([1, 2, 3, 4])
val2 = np.array([-1, -2, -3])

desired_final_result = np.array([-1, 1, 2, 3, -2, 4, -3])

val1val2 的编织由以下通过 mult1 的索引的逐元素处理定义mult2。两个 mult 数组的每个条目定义了从相应的 val 数组中选择多少个元素。我们通过 mult 数组逐元素进行; mult1[i] 的值决定了我们从 val1 中选择了多少条目,然后我们继续 mult2[ 的值i] 到 select 适当数量的 val2 条目,始终选择 val1 条目首先出现指数一。

注意 len(val1) = mult1.sum()len(val2) = mult2.sum(),所以我们总是以 len(desired_final_result) = len(val1) + len(val2) 最终数组结束。

最小示例的明确解释

问题

有没有办法使用矢量化函数,例如np.repeatand/ornp.choose解决我的问题?或者我是否需要求助于用 C 编写此计算并将其包装到 python?

这可以通过 NumPy 例程来完成,但我想出的最好的方法非常笨拙:

reps = numpy.empty([len(mult1)*2], dtype=int)
reps[::2] = mult1
reps[1::2] = mult2

to_repeat = numpy.empty_like(reps)
to_repeat[::2] = -1   # Avoid using 0 and 1 in case either of val1 or val2 is empty
to_repeat[1::2] = -2

indices = numpy.repeat(to_repeat, reps)
indices[indices==-1] = numpy.arange(len(val1))
indices[indices==-2] = numpy.arange(len(val1), len(val1) + len(val2))

final_result = numpy.concatenate([val1, val2])[indices]

正在为结果数组创建布尔索引:

mult = np.array([mult1, mult2]).ravel('F')
tftf = np.tile([True, False], len(mult1))
mask = np.repeat(tftf, mult)

result = np.empty(len(val1) + len(val2), int)
result[ mask] = val1
result[~mask] = val2

编辑 - 我相信这也有效:

idx = np.repeat(mult1.cumsum(), mult2)
result = np.insert(val1, idx, val2)

它很短,但可能不会更快。