2013-06-04 64 views
5

所以,我有單詞列表,我需要知道每個單詞在每個列表中出現的頻率。使用「.count(單詞)」的作品,但它太慢(每個列表有成千上萬的單詞,我有成千上萬的名單)。我可以欺騙numpy.histogram行爲像numpy.bincount?

我一直在努力加快與numpy的東西。我爲每個單詞生成一個唯一的數字代碼,所以我可以使用numpy.bincount(因爲它只適用於整數,而不是字符串)。但是我得到「ValueError:數組太大」。

所以現在我想捏捏numpy.histogram功能的「垃圾箱」的說法,使其回到我所需要的頻率計數(不知numpy.histogram似乎與大陣沒有問題)。但目前爲止沒有好處。那裏的任何人都碰巧做到了這一點?它甚至有可能嗎?有沒有我看不到的更簡單的解決方案?

+0

你的數組有多大!?我只用了一個10000000長度的整數數組,它工作得很好。我在得到錯誤之前耗盡了內存。 –

+1

我認爲這裏的問題涉及到你的獨特的數字代碼系統,而不是初始數組的大小。 np.bincount會創建一個長度等於1的數組+數組中的最大整數,如果您使用的編碼數量可笑的話,可能會導致問題。不過,我對np.bincount([1000000000])沒有任何問題。你的數字編碼方案是什麼? – cge

+1

啊,看起來錯誤發生在你正在嘗試垃圾箱的整數很大時。你可以用'foo = numpy.random.randint(2 ** 62,size = 1000)來模擬它; numpy.bincount(FOO)'。我想這是試圖創建一個巨大的unindexable數組來存儲所有的bin和numpy說沒有(這個錯誤是'multiarray/ctors.c')。你有幾個詞? –

回答

5

不要爲此使用numpy。改爲使用collections.Counter。它是爲這個用例而設計的。

+0

如果問題如上所述,這顯然是正確的做法! –

+0

太棒了!清潔和超快。 – Parzival

4

爲什麼不使用numpy.unique減少你的整數的最小集:

original_keys, lookup_vals = numpy.unique(big_int_string_array, return_inverse=True) 

然後你可以只是lookup_vals使用numpy.bincount,如果你需要回到原始的字符串唯一的整數,你可以只使用作爲索引的lookup_vals的值爲original_keys

所以,像這樣:

import binascii 
import numpy 

string_list = ['a', 'b', 'c', 'a', 'b', 'd', 'c'] 
int_list = [binascii.crc32(string)**2 for string in string_list] 

original_keys, lookup_vals = numpy.unique(int_list, return_inverse=True) 

bins = bincount(lookup_vals) 

而且,它避免了方的整數。

1

Thiago, 你也可以用scipy的itemfreq方法直接從分類變量中嘗試它。 下面是一個例子:

>>> import scipy as sp 
>>> import scipy.stats 
>>> rv = ['do', 're', 'do', 're', 'do', 'mi'] 
>>> note_frequency = sp.stats.itemfreq(rv) 
>>> note_frequency 
array([['do', '3'], 
     ['mi', '1'], 
     ['re', '2']], 
     dtype='|S2')