使用grouby进行计数

时间:2015-08-06 15:00:26

标签: python pandas

我有一个具有以下结构的文件(大约有10K行):

User Destination Country
123  34578       US
123  34578       US
345  76590       US
123  87640       MX
890  11111       CA
890  88888       CA
890  99999       CA

每个用户都可以访问位于不同国家/地区的多个目的地。我需要找出用户去往的唯一目的地的数量,独特目的地的中位数和平均值。国家也一样。我不知道如何使用groupby来实现这一目标。我设法通过将所有内容放在嵌套字典中来获取统计数据,但我觉得通过使用pandas数据帧和groubpy可能有更简单的方法。

我不是在寻找每个groupby部分的计数。我正在寻找类似的东西:平均来说,用户访问X个目的地和Y个国家。所以,我正在寻找所有groupby结果的汇总统计数据。

编辑。这是我的dict方法:

from collections import defaultdict
test=lambda: defaultdict(test)
conn_l=test()
with open('myfile') as f:
    for line in f:
        current=line.split(' ')
        s = current[0]
        d = current[1]
        if conn_l[s][d]:
            conn_l[s][d]+=1
        else:
            conn_l[s][d]=1

lengths=[]
for k,v in conn_l.items():
    lengths.append(len(v))

2 个答案:

答案 0 :(得分:1)

我认为这个可能比第一眼看上去有点困难(或者可能比我下面的方法更简单)。

ser = df.groupby('User')['Destination'].value_counts()

123   34578    2
      87640    1
345   76590    1
890   11111    1
      99999    1
      88888    1

value_counts()的输出是一个系列,然后您可以再次进行分组以获取唯一目的地的计数。

ser2 = ser.groupby(level=0).count()

User
123    2
345    1
890    3

为了清晰起见,你可以在一行上完成所有工作。

df.groupby('User')['Destination'].value_counts().groupby(level=0).count()

使用ser2,您应该能够完成所有其他事情。

ser2.median()
ser2.mean()

答案 1 :(得分:0)

同意JohnE,计算User的条目数量并不明显。 我发现:

df2 = df.groupby(['User','Destination'])
df3 = df2.size().groupby(level=0).count()

也有效,唯一的区别是df2是一个Dataframe.groupby而不是一个series.groupby,所以可能会有更多的功能,因为它保留了Country信息。

一个简单的例子:

for name, group in df2:
    print name, group

    (123, 34578)    User  Destination Country
0   123        34578      US
1   123        34578      US
(123, 87640)    User  Destination Country
3   123        87640      MX
(345, 76590)    User  Destination Country
2   345        76590      US
(890, 11111)    User  Destination Country
4   890        11111      CA
(890, 88888)    User  Destination Country
5   890        88888      CA
(890, 99999)    User  Destination Country
6   890        99999      CA

ser = df.groupby('User')['Destination']
for name, group in ser:
    print name, group

123 0    34578
1    34578
3    87640
Name: Destination, dtype: int64
345 2    76590
Name: Destination, dtype: int64
890 4    11111
5    88888
6    99999
Name: Destination, dtype: int64