简体   繁体   English

arrays 在 Python Numpy 中的逐元素乘法

[英]Elementwise multiplication of several arrays in Python Numpy

Coding some Quantum Mechanics routines, I have discovered a curious behavior of Python's NumPy. When I use NumPy's multiply with more than two arrays, I get faulty results.编写一些量子力学例程时,我发现了 Python 的 NumPy 的奇怪行为。当我使用 NumPy 与两个以上的 arrays 相乘时,我得到错误的结果。 In the code below, i have to write:在下面的代码中,我必须写:

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

which produces the correct result.产生正确的结果。 However, my initial formulation was this:然而,我最初的表述是这样的:

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

which does not produce an error message, but the wrong result.这不会产生错误消息,但会产生错误的结果。 Where is my fault in thinking that I could give three arrays to numpy's multiply routine?我认为我可以将三个 arrays 给 numpy 的乘法例程的错误在哪里?

Here is the full code:这是完整的代码:

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)

::NOTE:: this code only runs with NumPy 1.7.0 and higher! ::注意::此代码仅适用于NumPy 1.7.0及更高版本!

Your fault is in not reading the documentation :你的错在于没有阅读文档

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

multiply takes exactly two input arrays. multiply正好需要两个输入数组。 The optional third argument is an output array which can be used to store the result.可选的第三个参数是一个输出数组,可用于存储结果。 (If it isn't provided, a new array is created and returned.) When you passed three arrays, the third array was overwritten with the product of the first two. (如果未提供,则会创建并返回一个新数组。)当您传递三个数组时,第三个数组会被前两个数组的乘积覆盖。

For anyone stumbling upon this, the best way to apply an element-wise multiplication of n np.ndarray of shape (d, ) is to first np.vstack them and apply np.prod on the first axis:对于任何遇到此问题的人,应用 n np.ndarray形状(d, ) 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]

Yes!是的! Simply as doing * to np.arrays就像对 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)

Produce:生产:

[ 60 180 160]

I came across this question because I was interested in knowing the fastest way to multiply several arrays together.我遇到这个问题是因为我想知道将几个 arrays 相乘的最快方法。 I ended up writing a benchmark, and I'm surprised by what I found.我最终写了一个基准,我对我的发现感到惊讶。

I tested 3 methods:我测试了3种方法:

  1. Using pure python syntax a * b * c * d使用纯 python 语法a * b * c * d
  2. Using np.multiply.reduce使用 np.multiply.reduce
  3. Using np.stack followed by np.prod(..., axis=0)使用 np.stack 后跟 np.prod(..., axis=0)

I tested these methods with multiple numbers of arrays and array sizes.我用多个 arrays 和数组大小测试了这些方法。 I was very surprised to find that method 1 tends to be the best.我很惊讶地发现方法 1 往往是最好的。

在此处输入图像描述

The blue, orange, and green lines correspond to methods 1, 2, and 3 respectively.蓝色、橙色和绿色线分别对应方法 1、2 和 3。 The style of the line indicates how many arrays were multiplied together.线条的样式表示 arrays 相乘的次数。

The results are surprisingly consistent.结果出奇地一致。 Even when you have 8 arrays, it seems faster to just use a * b * c * d * e * f * g * h .即使你有 8 arrays,使用a * b * c * d * e * f * g * h似乎更快。 I'm not entirely sure why this is.我不完全确定这是为什么。 Perhaps Python sees this expression and does a divide-and-conquer combination style, whereas reduce is completely linear?也许 Python 看到这个表达式并进行分而治之的组合风格,而 reduce 是完全线性的?

Code for the benchmark is here:基准代码在这里:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM