2013-11-22 40 views
1

說我有一個函數調用f(m1)其中m1是一個numpy矩陣。現在,我想叫f上的矩陣幾乎是相同的m1Pythonic方式更新numpy矩陣的單個元素?

m2 = m1.copy() 
m2[ 2, 7 ] = 43 # or m2[ 2, 7 ] += 43 
f(m2) 

有一種優雅的f(...)的一行來做到這一點?

+1

這也正是這樣做的方式。但是,如果您的代碼的組織方式使您可以同時生成'm1'和'm2',則可能會有一種更優雅,更高效的方式。 – shx2

回答

1

在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 

但是,如果您只需添加一行修改矩陣,上面的選項就更加複雜。

0

爲了教育學的緣故,這裏有一個功能性的方法來做到這一點。 np.where其實不正是你想要的,但棘手的部分是,它接受一個布爾條件,而不是一個指標:

f(np.where(condition, 43, m1)) 

它發送43f無論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.]]) 
相關問題