2016-01-20 77 views
0

給定一百萬條記錄的大型數據集,我正在尋找方法來做一個group。 我是新來的python,但我知道在SQL中有一個groupby函數,我猜它可能適用。Groupby在python的列表中

我想要實現這算什麼,

["A", 4] 
["B", 4] 
["F", 3] 
["A", 4] 
["B", 1] 

["A", (4,4)] 
["B", (1,4)] 
["F", (3)] 

我也在尋找一種有效的方式來計算評分列表的平均值。所以最後的輸出應該是:

["A", 4] 
["B", 2.5] 
["F", 3] 

我試圖做一個迭代的方法進行,但拋出的錯誤是「有太多的數據解壓」。這是我的解決方案,它不適合數據集。

len = max(key for (item, key) in results) 
newList = [[] for i in range(len+1)] 
for item, key in results: 
    newList[key].append(item) 

我正在尋找有效的方法來做到這一點,有沒有辦法在列表理解中做groupby?謝謝!

+0

誤差意味着數據集**不是**形式'的[(X,Y),...]'。你確定'結果'是'(x,y)'對的迭代嗎? – freakish

回答

2

有的確是一個itertools方法groupby,只是知道它要求事先對數據進行排序,請參閱此處的文檔https://docs.python.org/2/library/itertools.html#itertools.groupby

但是從您發佈的代碼看,您似乎並不需要進行分組,您只需要計數,對吧?那麼你最好使用collections.Counter。請注意,它需要項目可哈希,所以你想要將這些列表轉換爲元組。

>>> lst = [tuple(i) for i in ls] 
>>> collections.Counter(lst) 
Counter({('A', 4): 2, ('F', 3): 1, ('B', 1): 1, ('B', 4): 1}) 

關於效率...不知道你會票價很好加載在內存中的整個數據集,但你可以使用弗拉德於迭代描述的defaultdict方法。

關於平均數,如果你真的想用groupby,那麼你可以做這樣的事情:

>>> def average(lst): 
...  return 1.0*sum(lst)/len(lst) if lst else 0.0 
>>> [(i[0],average([j[1] for j in i[1]])) for i in itertools.groupby(sorted(ls),key=lambda i:i[0])] 
[('A', 4.0), ('B', 2.5), ('F', 3.0)] 
3

我認爲以下將是一個小數據集合理的方法。

from collections import defaultdict 

ls = [ 
    ["A", 4], 
    ["B", 4], 
    ["F", 3], 
    ["A", 4], 
    ["B", 1], 
] 

d = defaultdict(list) 
for key, val in ls: 
     d[key].append(val) 

# Prints [['A', (4, 4)], ['B', (4, 1)], ['F', (3,)]] 
print [[k, tuple(l)] for k, l in d.items()] 

# prints [['A', 4.0], ['B', 2.5], ['F', 3.0]] 
print [[k, float(sum(l))/len(l)] for k, l in d.items()] #* 

*在Python 2.x中,使用iteritems()代替items(),看到this answer

稍微好一點,如果你只關心平均水平,你不會需要存儲的一切,一鍵映射到:

d = defaultdict(lambda: (0, 0)) 
for key, val in ls: 
    cnt, total = d[key] 
    d[key] = (cnt + 1, total + val) 

print [[k, float(total)/cnt] for k, (cnt, total) in d.items()] 
0

您可能需要習慣於對付像這樣的數據電子表格類型的接口。這是一個比你想要的更大的實現,但是從長遠來看,繪製和繪製圖形會更容易。這個例子使用熊貓和numpy。

亮點來自這個問題上的數據,並將其複製:

name value 
A 4 
B 4 
F 3 
A 4 
B 1 

您可以進入IPython中,並開始鍵入此操作的設置。

import pandas as pd 
import numpy as np 

data= pd.from_clipboard() 

現在出現有趣的部分。 你可以使用數據透視表,它可以通過你想要的任何功能對所有這些值進行分組。

pd.pivot_table(data=data, index='name', aggfunc=np.mean) 

返回

 value 
name  
A  4.0 
B  2.5 
F  3.0