假设下面的numpy数组
import numpy as np
array_a = np.arange(1,10).reshape(3,3)
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
如何在不使用任何循环的情况下将前一行与后一行迭代地相乘(前一行的值,除了row = 0,是乘法的乘积)。
例如,以上array_a
的期望输出为
[[1, 2, 3
[4, 10, 18]
[28, 80, 162]]
我知道像np.dot
和np.einsum
这样的numpy矩阵乘法函数,但是我无法提出可以使用这些函数的问题。如果有的话,也欢迎使用熊猫解决方案。感谢您的指导。
答案 0 :(得分:0)
np.cumprod是一个很好的选择,如果您只需要乘法。
import numpy as np
array_a = np.arange(1,10).reshape(3,3)
array_b = np.cumprod(array_a, axis=0)
另一个非常有效的选择是使用生成器。 这有点慢,但也更通用
def generator(arr):
cnt_up = len(arr)
cnt_down = 0
if cnt_down == 0:
yield arr[0]
while cnt_up > 1:
cnt_up -= 1
cnt_down += 1
yield arr[cnt_down-1] * arr[cnt_down]
gen = generator(array_a)
array_b = np.stack([g for g in gen])
最后一个选项是对其他操作使用递归 (速度会慢很多,因此首选np.cumpcrod / generator)
import numpy as np
array_a = np.arange(1,10).reshape(3,3)
def recursive(arr):
if len(arr) <= 1:
return arr
else:
return arr[-1] * recursive(arr[:-1])
array_b = np.stack([recursive(array_a[:i])[0] for i in range(1, len(array_a)+1)])
第二种方法是是否要使用其他自定义公式。
我用了%timeit,我得到了:
cumpcrod为3纳秒,
9纳秒的生成器选项
25纳秒的递归