2015-10-19 70 views
2

比方說,我有這樣一個矩陣:的elementwise乘法忽略矩陣的某些行

import numpy as np 

a = np.array([[1, 2, 3], [89, 43, 2], [12, -3, 4], [-2, 4, 7]]) 

array([[ 1, 2, 3], 
     [89, 43, 2], 
     [12, -3, 4], 
     [-2, 4, 7]]) 

和看起來像這樣一個向量:

b = np.array([1, 2, 3]) 

如果我現在想要做的elementwise乘我可以簡單地做

c = a * b 

,並獲得

array([[ 1, 4, 9], 
     [89, 86, 6], 
     [12, -6, 12], 
     [-2, 8, 21]]) 

我的問題是:如何才能對我矩陣中的某些行進行這種乘法運算?我現在做的是這樣的:

E = a.copy() 

# ignore these rows 
ignInd = [1, 3] 

for ind in xrange(a.shape[0]): 
    if ind not in ignInd: 
     E[ind, :] = a[ind, :] * b 

矩陣E看起來所需的(行1和3是一樣a):

array([[ 1, 4, 9], 
     [89, 43, 2], 
     [12, -6, 12], 
     [-2, 4, 7]]) 

能有人想出了一個聰明的解決方案比這個?

+0

也許擴展向量爲一個矩陣,有些行都是1? –

+0

@tobias_k:這可能工作,但列應該是1而不是行。我嘗試了,謝謝! – Cleb

回答

4

好像你可能只是做乘法,然後放回去要忽略原始數據...

>>> import numpy as np 
>>> a = np.array([[1,2,3],[89,43,2],[12, -3, 4], [-2, 4, 7]]) 
>>> b = np.array([1,2,3]) 
>>> c = a * b 
>>> ignInd = [1,3] 
>>> c[ignInd, :] 
array([[89, 86, 6], 
     [-2, 8, 21]]) 
>>> c[ignInd, :] = a[ignInd, :] 
>>> c 
array([[ 1, 4, 9], 
     [89, 43, 2], 
     [12, -6, 12], 
     [-2, 4, 7]]) 
+0

太棒了,這也很好,謝謝!我喜歡它,並可能在稍後接受它,這取決於其他用戶的答案。 – Cleb

+0

我不希望這是快速的,因爲它執行了許多乘法運算,但有趣的是,我做了一些運行時測試,證明它非常快!有趣的東西真的。 – Divakar

4

您可以直接用另一個NumPy數組索引一個NumPy數組。你的情況,你必須要忽略行的索引,這樣你就可以建立索引的數組包括來自該

In [21]: ignInd = [1,3] #ignore these rows 
In [22]: ind = np.array([i for i in range(a.shape[0]) if i not in ignInd]) 
In [23]: E2 = a.copy() 

In [24]: E2[ind,:] = a[ind,:]*b 

In [25]: E2 
Out[25]: 
array([[ 1, 4, 9], 
     [89, 43, 2], 
     [12, -6, 12], 
     [-2, 4, 7]]) 

編輯:作爲@DSM意見,對於大數組這將是使用NumPy的矢量化方法構建索引數組效率更高, ind = np.setdiff1d(np.arange(len(a)), ignInd)而不是上面使用的列表理解。

+0

這很好,謝謝!我喜歡它,並可能接受它遲到,取決於其他答案的質量。 – Cleb

+1

請注意,您可以使用向量操作符來獲得'ind',例如'np.setdiff1d(np.arange(len(a)),ignInd)',但當列表非常小時,這並不重要。 – DSM

+0

@DSM:感謝您的評論!實際上,我的數組當然要大得多,所以我會用你的建議來確定ind。 – Cleb

-1

爲第1行中一個

a[0] = a[0] * b 

..和等的其他行。

+0

謝謝,但這並不能解決問題;這就是我在for循環中所做的事情,而「等等」實際上是關鍵部分。 – Cleb

+0

對不起,我不理解你的問題。您可以使用該行的索引直接訪問任何行。 – DrBwts

+0

沒問題,我總是欣賞輸入:) – Cleb

1

您可以使用boolean indexingnp.in1d選擇排除在給定指標的行名單。實現看起來像這樣 -

E = a.copy() 
mask = ~np.in1d(np.arange(a.shape[0]),ignInd,) 
E[mask] = a[mask]*b 
+0

謝謝,這也很好。我喜歡它,並可能在稍後接受它,這取決於其他答案的質量。 – Cleb

+0

@Cleb不要急!只是好奇,輸入的數據是什麼? – Divakar

+0

取決於,但通常是像2000 * 2000矩陣。我必須多次進行這些計算,所以速度真的很重要。 – Cleb