2012-03-22 36 views
4

我有一個很大的稀疏矩陣。我想對該稀疏矩陣中的所有元素採取log4。我嘗試使用numpy.log(),但它不適用於矩陣。以稀疏矩陣取對數函數的有效方法

我也可以一行一行地取對數。然後我用一個新的粉碎舊行。

# Assume A is a sparse matrix (Linked List Format) with float values as data 
# It is only for one row 

import numpy as np 
c = np.log(A.getrow(0))/numpy.log(4) 
A[0, :] = c 

這並不像我預料的那麼快。有沒有更快的方法來做到這一點?

回答

0

我想我用非常簡單的方法解決它。很奇怪,沒有人能立即回答。

# Let A be a COO_matrix 
import numpy as np 
from scipy.sparse import coo_matrix 
new_data = np.log(A.data+3)/np.log(4) #3 is not so important. It can be 1 too. 
A = coo_matrix((new_data, (A.row, A.col)), shape=A.shape) 
+4

沒有人提出這個解決方案,因爲它在數學上不正確。 'log(x)'可能與'log(x + 1)'非常不同! (例如:'log(0.000001)= -6','log(0.0000001 + 1 = 0 and a bit')。 – 2012-03-23 02:02:37

+0

對於不合適的問題抱歉,我沒有提及所有的數據都是正數並且大於1。是TF(term frequency)矩陣的值,我認爲沒有問題 – Thorn 2012-03-23 10:29:55

+0

這裏絕對沒有理由在這裏添加3(或任何東西),因爲'A.data'中的條目都不爲0。你確實想要添加一個常量的方法,使用一個更小的方法!添加'1e-16'將會有同樣的效果,即不會使用'log(0)',但引入的錯誤更少:使用[適當的標識](http://en.wikipedia.org/wiki/List_of_logarithmic_identities#Summation.2Fsubtraction),它是'log(x + eps)= log(x)+ log(1 + eps/a)',其中引入的錯誤是如果「eps/a」幾乎爲0,則爲0附近0 – Dougal 2012-03-23 14:37:34

2

您可以直接修改data屬性:

>>> a = np.array([[5,0,0,0,0,0,0],[0,0,0,0,2,0,0]]) 
>>> coo = coo_matrix(a) 
>>> coo.data 
array([5, 2]) 
>>> coo.data = np.log(coo.data) 
>>> coo.data 
array([ 1.60943791, 0.69314718]) 
>>> coo.todense() 
matrix([[ 1.60943791, 0.  , 0.  , 0.  , 0.  , 
      0.  , 0.  ], 
     [ 0.  , 0.  , 0.  , 0.  , 0.69314718, 
      0.  , 0.  ]]) 

請注意,這並不正確,如果稀疏格式已經重複的元素(這是有效的COO格式)工作;它將單獨記錄日誌,並且log(a) + log(b) != log(a + b)。您可能首先要轉換爲CSR或CSC(這很快)以避免此問題。

當然,您還必須添加檢查稀疏矩陣是否採用不同的格式。如果您不想在原地修改矩陣,只需構建一個新的稀疏矩陣,就像您在答案中所做的那樣,但不添加3,因爲在這裏完全沒有必要。

+0

我的解決方案和您的解決方案有什麼區別?你建議只有在你的解決方案中已經提出作爲評論的3沒有必要。 – Thorn 2012-03-24 19:53:16

+0

@Thorn我實際上最初誤解了你的解決方案(以爲你在整個矩陣中加了3,所以做了大量不必要的標誌)。你說得對,他們基本上是一樣的。 – Dougal 2012-03-24 20:42:29