Pythonic方法更新numpy矩阵的单个元素?

时间:2013-11-22 10:27:19

标签: python numpy matrix

假设我有一个函数调用f(m1),其中m1是一个numpy矩阵。现在,我想在一个与f几乎相同的矩阵上调用m1

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

是否有一个优雅的f( ... )单行代码?

2 个答案:

答案 0 :(得分: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

但是,如果您只需添加一行修改矩阵,则上述选项会更复杂。

答案 1 :(得分:0)

对于教育学而言,这是一种功能性的方法。 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.]])