我有两个不等长 val1 和 val2 的数组,我试图以等长数组定义的特定方式编织在一起mult1 和 mult2 。一般来说,我的数组很长(~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])
val1 和 val2 的编织由 mult1 和 mult2 <的索引通过以下逐元素处理来定义/ em>的。两个 mult 数组的每个条目定义了从相应的 val 数组中选择的元素数量。我们通过 mult 数组以元素方式进行; mult1 [i] 的值确定我们从 val1 中选择的条目数,然后我们继续使用 mult2 [i] 的值来选择适当数量的 val2 条目,始终为每个索引i选择 val1 条目。
请注意 len(val1)= mult1.sum()和 len(val2)= mult2.sum(),所以我们总是以最终数组结束 len(desired_final_result)= len(val1)+ len(val2)。
由于 mult1 的 i = 0 条目 0 ,我们从< 0 条目中选择 0 条目em> val1 并继续进入 mult2 的 i = 0 , 1 ,因此我们选择 1 val2 的条目。这解释了为什么desired_final_result的第一个条目是-1。
由于 mult1 的 i = 1 条目 1 ,我们从< 1 条目中选择 1 条目em> val1 并继续进入 mult2 的 i = 1 , 0 ,因此选择 0 < / strong>来自 val2 的条目。这解释了为什么desired_final_result的第二个条目是1.
由于 mult1 的 i = 2 条目 2 ,我们选择下一个 2 条目从 val1 继续进入 mult2 的 i = 2 , 1 ,所以我们选择下一个来自 val2 的 1 条目。这解释了为什么desired_final_result的条目2-4是2,3,-2。
由于 mult1 的 i = 3 1 ,我们选择下一个 1 条目从 val1 继续进入 mult2 的 i = 3 ,这也是 1 ,所以我们选择来自 val2 的下一个 1 条目。这解释了为什么desired_final_result的条目5-6是4,-3。
最后,由于 mult1 和 mult2 的 i = 4 0 ,我们没有什么可做的,我们的阵列已经填满。
有没有办法使用矢量化函数,如 np.repeat 和/或 np.choose 来解决我的问题?或者我是否需要在C中编写此计算并将其包装到python中?
答案 0 :(得分:4)
在结果数组中创建布尔索引:
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)
很简短,但可能不会更快。
答案 1 :(得分:2)
这可以通过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]