說我有一個函數調用f(m1)
其中m1
是一個numpy矩陣。現在,我想叫f
上的矩陣幾乎是相同的m1
:Pythonic方式更新numpy矩陣的單個元素?
m2 = m1.copy()
m2[ 2, 7 ] = 43 # or m2[ 2, 7 ] += 43
f(m2)
有一種優雅的f(...)
的一行來做到這一點?
說我有一個函數調用f(m1)
其中m1
是一個numpy矩陣。現在,我想叫f
上的矩陣幾乎是相同的m1
:Pythonic方式更新numpy矩陣的單個元素?
m2 = m1.copy()
m2[ 2, 7 ] = 43 # or m2[ 2, 7 ] += 43
f(m2)
有一種優雅的f(...)
的一行來做到這一點?
在Python中,每一項任務是一個語句,而不是一個表達式,所以你不能這樣做 -
f(m2[2,7] = 43)
或
if (a = 1+2)
我相信你能做到
f(modify_matrix(m1))
並定義一個修改m1矩陣的單獨方法。
def modify_matrix(m1):
m1[2,7] = 2
return m1
但是,如果您只需添加一行修改矩陣,上面的選項就更加複雜。
爲了教育學的緣故,這裏有一個功能性的方法來做到這一點。 np.where
其實不正是你想要的,但棘手的部分是,它接受一個布爾條件,而不是一個指標:
f(np.where(condition, 43, m1))
它發送43
到f
無論condition
得到滿足,其他地方則只是將m1
,因此這將如果我們知道你選擇要改變的元素的標準,可能會更簡單。因此,最棘手的部分是創建布爾數組,這無論如何都有點浪費。
np.where(np.all(np.indices(m1.shape) == np.array([2, 7])[:, None, None], 0), 43, m1)
或等價:
np.where(np.all(np.rollaxis(np.indices(m1.shape),0,3) == np.array([2, 7]), -1), 43, m1)
我可以發誓,有是採取了一個指標,而不是一個面具的等效功能,但遺憾的是它似乎採取指數類似的功能(np.put
,如)修改數組,而不是在功能上返回一個新數組。 np.choose
也可以工作,但創建「選擇」數組(與條件掩碼數組相比)具有相同的問題。
在行動:
In [66]: m1 = np.zeros((4, 9))
In [67]: np.where(np.all(np.indices(m1.shape) == np.array([2, 7])[:,None, None], 0), 43, m1)
Out[67]:
array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 43., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
In [68]: np.where(np.all(np.rollaxis(np.indices(m1.shape),0,3) == np.array([2, 7]), -1), 43, m1)
Out[68]:
array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 43., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
這也正是這樣做的方式。但是,如果您的代碼的組織方式使您可以同時生成'm1'和'm2',則可能會有一種更優雅,更高效的方式。 – shx2