2012-10-26 65 views
1

組成不同長度的獨特陣列的頻率名單上有不同長度的numpy的陣列,其中一些重複,像這樣的列表:如何在numpy的

import numpy as np 

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

從這個名單,我想獨特數組的數量(如序列上的直方圖)。

由於numpy的數組是沒有可哈希,我通過轉換陣列以他們的字符串表示,並將它作爲用於與itertools.groupby類似於this method分組的密鑰,

import itertools 

sorted_strings = sorted([str(p) for p in multi]) 
groups = [(k, len(list(g))) for k, g in itertools.groupby(sorted_strings)] 
print(groups) 

這種情況的輸出是這樣:

[('[1 2 3 4]', 1), ('[1 2 3]', 2), ('[1 2]', 2)] 

這是正確的,但我不知道是否有一個更優雅的解決方案,或者如果有存儲比數組列表這些數據更好的方法。

+0

也許你可以使用numpy的吧,不過說實話,因爲你的陣列似乎小了,除非你有一些很好的理由或使用完全不同的方法,我會說只是使用元組,他們是可散列的...字符串真的是一個*大*黑客,你會怎麼回到一個體面的類型... – seberg

+0

謝謝你的有用答案和評論!在我的應用程序中,序列更長,並且有更多。但是由於看起來我需要將numpy數組轉換爲可哈希值,所以元組確實比字符串更有意義。 – user1248490

回答

2

您可以使用collections.Counter

>>> from collections import Counter 
>>> 
>>> Counter(map(tuple, multi)).most_common() 
[((1, 2), 2), ((1, 2, 3), 2), ((1, 2, 3, 4), 1)] 

爲了獲得最不常見的:

>>> Counter(map(tuple, multi)).most_common()[::-1] 
[((1, 2, 3, 4), 1), ((1, 2, 3), 2), ((1, 2), 2)] 
0

如果你堅持用Python版本沒有定義collections.Counter,你可以使用您鏈接的方法:

base = sorted(tuple(m) for m in multi) 
G=[(k,len(list(g))) for (k,g) in itertools.groupby(base)] 

你基本上將每個數組轉換成一個元組(注意基於Counter的方法依賴於相同的方法)。

注意,你可能想確保你的陣列進行排序,使np.array([2,1])np.array([1,2])被認爲是等價的:

base = sorted(tuple(sorted(m)) for m in multi)