2016-01-20 60 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