簡體   English   中英

arrays 在 Python Numpy 中的逐元素乘法

[英]Elementwise multiplication of several arrays in Python Numpy

編寫一些量子力學例程時,我發現了 Python 的 NumPy 的奇怪行為。當我使用 NumPy 與兩個以上的 arrays 相乘時,我得到錯誤的結果。 在下面的代碼中,我必須寫:

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

產生正確的結果。 然而,我最初的表述是這樣的:

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

這不會產生錯誤消息,但會產生錯誤的結果。 我認為我可以將三個 arrays 給 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及更高版本!

你的錯在於沒有閱讀文檔

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

multiply正好需要兩個輸入數組。 可選的第三個參數是一個輸出數組,可用於存儲結果。 (如果未提供,則會創建並返回一個新數組。)當您傳遞三個數組時,第三個數組會被前兩個數組的乘積覆蓋。

對於任何遇到此問題的人,應用 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]

是的! 就像對 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]

我遇到這個問題是因為我想知道將幾個 arrays 相乘的最快方法。 我最終寫了一個基准,我對我的發現感到驚訝。

我測試了3種方法:

  1. 使用純 python 語法a * b * c * d
  2. 使用 np.multiply.reduce
  3. 使用 np.stack 后跟 np.prod(..., axis=0)

我用多個 arrays 和數組大小測試了這些方法。 我很驚訝地發現方法 1 往往是最好的。

在此處輸入圖像描述

藍色、橙色和綠色線分別對應方法 1、2 和 3。 線條的樣式表示 arrays 相乘的次數。

結果出奇地一致。 即使你有 8 arrays,使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM