2013-04-01 25 views
3

如果这对于使用熊猫来说太棘手,那么对熊猫来说是新的并且好奇。使用熊猫进行棘手的聚合

例输入:

time  person game_id won 
----------------------------------- 
12:34:01 John  3   False 
12:34:04 Ringo 2   True 
12:35:05 John  3   False 
12:36:01 John  3   True 
12:36:12 Ringo 3   True 
12:36:41 Paul  4   False 
12:37:01 George 2   False 
12:37:41 George 2   False 

它显示了一个号码打了一些比赛随着时间的人。 赢得的列表示该人是否在当时获胜。

我想要输出的是有多少人赢得每场比赛至少一次。 但是还有多少人玩过这款游戏并且从来没有获胜。

输出示例:

game_id won  count 
----------------------- 
2   True 1 
      False 1 
3   True 2 
      False 0 
4   True 0 
      False 1 
+1

不,不是太靠谱。你可以通过几种方式在几行中做到这一点:我使用'groupby'和'.nunique()'来做硬件。 (对我来说,统计总球员和曾经获胜者的人数似乎更加容易,然后减去他们以获得从未获胜者。) – DSM

+0

嗨,Yasir!如果不使用熊猫,我会按照n * log(n)的顺序执行一个方法。它的工作原理如下:字典: 首先我按人排序,然后由game_id排序,最后以won排序。然后循环遍历所有行并为(game_id,won = True)增加一个计数器(如果存在“True”条目)。否则,如果只有False条目,我会增加(game_id,won = False)。 最后我会打印出结果字典。 有可能是一种更优雅的方式来做到这一点使用熊猫。 –

+0

感谢帝斯曼!如果你能分享一些令人惊叹的细节。试图为laaaaarge数据集执行此操作。所以速度是关键。 –

回答

6

或多或少什么@DSM在说:

In [3]: grouped = df.groupby('game_id') 

In [4]: won = grouped.won.sum() 

In [5]: DataFrame({True: won, False: grouped.person.nunique() - won}).stack() 
Out[5]: 
game_id  
2  False 1 
     True  1 
3  False 0 
     True  2 
4  False 1 
     True  0 
dtype: float64 
+0

感谢熊猫,她是超级巨星! –

4
s1 = (~df.groupby(["game_id", "person"]).won.agg(np.any)).groupby(level=0).sum() 
s2 = df.groupby(["game_id", "won"]).person.agg(lambda s:s.nunique()) 
df2 = s2.unstack() 
df2[False] = s1 
df2.fillna(0).unstack().swaplevel(0, 1).sort_index() 
+0

谢谢HYRY。您还可以处理由同一个人胜出的多场比赛的情况非常好。 –