Python Numpy中多个数组的逐元素乘法

11
编写一些量子力学例程时,我发现 Python 的 NumPy 存在一个奇怪的行为。当我使用 NumPy 的 multiply 函数时使用超过两个数组,我会得到错误的结果。在下面的代码中,我必须这样写:
f = np.multiply(rowH,colH)
A[row][col]=np.sum(np.multiply(f,w))

该程序可以产生正确的结果。然而,我最初的表述是:

A[row][col]=np.sum(np.multiply(rowH, colH, w))

它不会产生错误信息,但会得出错误的结果。我在想,我将三个数组输入给NumPy的乘法例程,错在哪里?

以下是完整的代码:

from numpy.polynomial.hermite import Hermite, hermgauss
import numpy as np
import matplotlib.pyplot as plt

dim = 3
x,w = hermgauss(dim)
A = np.zeros((dim, dim))
#build matrix
for row in range(0, dim):
    rowH = Hermite.basis(row)(x)
    for col in range(0, dim):
        colH = Hermite.basis(col)(x)
        #gaussian quadrature in vectorized form
        f = np.multiply(rowH,colH)
        A[row][col]=np.sum(np.multiply(f,w))
print(A)

::注意::该代码仅支持NumPy 1.7.0及以上版本!

4个回答

19

你的问题在于没有阅读文档

numpy.multiply(x1, x2[, out])

multiply函数只接受两个输入数组。可选的第三个参数是一个输出数组,可用于存储结果。(如果未提供,则创建并返回一个新数组。)当您传递三个数组时,第三个数组会被第一和第二个数组的乘积重写。


1
好的,我的错 :-)。我应该删除这篇帖子还是你认为它对其他人有用? - seb
9
留下它。帮了我 :) - mrjrdnthms
2
那么,在最新版本中,是否有将多个数组乘在单个调用中的选项,或者我们必须链接这些调用? - Nagabhushan S N

19

对于任何偶然发现的人,将形状为(d, )的n个np.ndarray进行逐元素相乘的最佳方法是先使用np.vstack将它们堆叠起来,然后在第一个轴上应用np.prod

>>> import numpy as np
>>>
>>> arrays = [
...   np.array([1, 2, 3]),
...   np.array([5, 8, 2]),
...   np.array([9, 2, 0]),
... ]
>>>
>>> print(np.prod(np.vstack(arrays), axis=0))
[45 32  0]

6
假设输入的数组是一维的。如果输入的是多维数组,使用 np.prod(np.array(arrays), axis=0)) 效果更好。 - Shlomi A

2
是的!就像对np.arrays做*一样简单。最初的回答。
import numpy as np
a=np.array([2,9,4])
b=np.array([3,4,5])
c=np.array([10,5,8])
d=a*b*c
print(d)

产生:

[ 60 180 160]

1

我看到这个问题是因为我想知道将多个数组相乘的最快方法。我最终编写了一个基准测试,我对结果感到惊讶。

我测试了3种方法:

  1. 使用纯Python语法 a * b * c * d
  2. 使用np.multiply.reduce
  3. 使用np.stack,然后是np.prod(..., axis=0)

我使用多个数组和数组大小进行了测试。我很惊讶地发现方法1往往是最好的。

enter image description here

蓝色、橙色和绿色线分别对应于方法1、2和3。线的样式表示相乘的数组数。

结果出奇的一致。即使有8个数组,似乎使用 a * b * c * d * e * f * g * h 更快。我不完全确定为什么会这样。也许Python看到这个表达式并执行分治组合风格,而reduce则完全是线性的?

基准测试的代码在这里:

https://github.com/Erotemic/misc/blob/main/tests/python/bench_np_reduce_vs_repeat.py


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接