[英]Python, numpy.array slicing, altering array values with slices
我有一個數值積分任務,其中我們用積分公式近似積分。 我的問題是任務需要我避免循環並使用矢量化變量,這將是片嗎?
我有n個值的np.array對象,我必須使用特定的公式來更改此數組的每個值。 問題在於公式中使用此數組在點i處的值來更改位置。使用for循環將很容易:
x = np.array([...])
for i in range(0,n):
x[i]=f(x[i]+a)*b`
(a,b一些其他變量)我該如何用切片呢? 我必須對數組的所有元素執行此操作,因此將類似於:
x[:]=f(x[???]+a)*b
我如何從數組中獲得正確的位置到公式中? 像x [:]這樣的切片指令僅遍歷我的整個對象。 有什么方法可以保存我當前所在的索引嗎? 我試圖搜索但什么也沒找到。 另一個問題是我什至不知道如何正確放置搜索請求...
您可能會混淆兩個問題
在
x = np.array([...])
for i in range(0,n):
x[i]=f(x[i]+a)*b`
您將x
元素一一更改,並將它們一一傳遞給f
。
x[:] = ...
使您可以立即更改x
所有元素,但是源(方程式的右側)必須生成所有這些值。 但是通常您不需要分配值。 而是使用x = ...
速度和內存效率一樣快。
在RHS上使用x[:]
對您沒有任何幫助。 如果x
是一個列表,則會進行復制; 如果x
是一個數組,則只返回一個view
,即一個具有相同值的數組。
關鍵問題是,您的f(...)
函數接受什么? 如果它使用+
, *
類的操作以及np.sin
類的np.sin
,則可以為其提供一個數組,它將返回一個數組。
但是,如果它僅適用於標量(包括使用諸如math.sin
類的math.sin
),則您必須為其提供標量,即x[i]
。
讓我們嘗試解壓縮該評論(作為對原始問題的編輯可能會更好)
我的時間間隔必須短一些。
x = np.linspace(start,end,pieceAmount)
function f
quadrature formula
b (weights or factors)
c (function values)
b1*f(x[i]+c1)+...+bn*f(x[i]+cn)
例如
In [1]: x = np.arange(5)
In [2]: b = np.arange(3)
In [6]: c = np.arange(4,7)*.1
我們可以通過廣播為所有x
和c
做x[i]+c
In [7]: xc = x + c[:,None]
In [8]: xc
Out[8]:
array([[ 0.4, 1.4, 2.4, 3.4, 4.4],
[ 0.5, 1.5, 2.5, 3.5, 4.5],
[ 0.6, 1.6, 2.6, 3.6, 4.6]])
如果f
是像np.sin
這樣的函數,它接受任何數組,則可以將xc
傳遞給該函數,從而獲得大小相同的數組。
再次使用廣播,我們可以進行b[n]*f(x[i]+c[n])
計算
In [9]: b[:,None]* np.sin(xc)
Out[9]:
array([[ 0. , 0. , 0. , -0. , -0. ],
[ 0.47942554, 0.99749499, 0.59847214, -0.35078323, -0.97753012],
[ 1.12928495, 1.99914721, 1.03100274, -0.88504089, -1.98738201]])
然后我們可以求和,得到一個形狀類似於x
的數組:
In [10]: np.sum(_, axis=0)
Out[10]: array([ 1.60871049, 2.99664219, 1.62947489, -1.23582411, -2.96491212])
那就是點或矩陣乘積:
In [11]: b.dot(np.sin(xc))
Out[11]: array([ 1.60871049, 2.99664219, 1.62947489, -1.23582411, -2.96491212])
正如我前面提到的,我們可以通過
x = b.dot(f(x+c[:,None])
像這樣的簡單表達式的關鍵是f
接受數組。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.