【发布时间】:2013-03-13 10:21:53
【问题描述】:
我的问题是如何计算 pandas 中多个变量的频率。 我有这个数据框:
d1 = pd.DataFrame( {'StudentID': ["x1", "x10", "x2","x3", "x4", "x5", "x6", "x7", "x8", "x9"],
'StudentGender' : ['F', 'M', 'F', 'M', 'F', 'M', 'F', 'M', 'M', 'M'],
'ExamenYear': ['2007','2007','2007','2008','2008','2008','2008','2009','2009','2009'],
'Exam': ['algebra', 'stats', 'bio', 'algebra', 'algebra', 'stats', 'stats', 'algebra', 'bio', 'bio'],
'Participated': ['no','yes','yes','yes','no','yes','yes','yes','yes','yes'],
'Passed': ['no','yes','yes','yes','no','yes','yes','yes','no','yes']},
columns = ['StudentID', 'StudentGender', 'ExamenYear', 'Exam', 'Participated', 'Passed'])
到下面的结果
Participated OfWhichpassed
ExamenYear
2007 3 2
2008 4 3
2009 3 2
(1) 我尝试的一种可能性是计算两个数据帧并绑定它们
t1 = d1.pivot_table(values = 'StudentID', rows=['ExamenYear'], cols = ['Participated'], aggfunc = len)
t2 = d1.pivot_table(values = 'StudentID', rows=['ExamenYear'], cols = ['Passed'], aggfunc = len)
tx = pd.concat([t1, t2] , axis = 1)
Res1 = tx['yes']
(2) 第二种可能性是使用聚合函数。
import collections
dg = d1.groupby('ExamenYear')
Res2 = dg.agg({'Participated': len,'Passed': lambda x : collections.Counter(x == 'yes')[True]})
Res2.columns = ['Participated', 'OfWhichpassed']
至少可以说,这两种方式都很尴尬。 这是如何在 pandas 中正确完成的?
P.S:我也试过 value_counts 而不是 collections.Counter 但无法让它工作
供参考:几个月前,我向 R here 提出了类似的问题,plyr 可以提供帮助
---- 更新 ------
用户 DSM 是对的。所需的表格结果有误。
(1) 选项一的代码是
t1 = d1.pivot_table(values = 'StudentID', rows=['ExamenYear'], aggfunc = len)
t2 = d1.pivot_table(values = 'StudentID', rows=['ExamenYear'], cols = ['Participated'], aggfunc = len)
t3 = d1.pivot_table(values = 'StudentID', rows=['ExamenYear'], cols = ['Passed'], aggfunc = len)
Res1 = pd.DataFrame( {'All': t1,
'OfWhichParticipated': t2['yes'],
'OfWhichPassed': t3['yes']})
它会产生结果
All OfWhichParticipated OfWhichPassed
ExamenYear
2007 3 2 2
2008 4 3 3
2009 3 3 2
(2) 对于选项 2,感谢用户 herrfz,我弄清楚了如何使用 value_count,代码将是
Res2 = d1.groupby('ExamenYear').agg({'StudentID': len,
'Participated': lambda x: x.value_counts()['yes'],
'Passed': lambda x: x.value_counts()['yes']})
Res2.columns = ['All', 'OfWgichParticipated', 'OfWhichPassed']
这将产生与 Res1 相同的结果
我的问题仍然存在:
使用选项 2,是否可以两次使用相同的变量(用于另一个操作?)可以为结果变量传递自定义名称吗?
----一个新的更新----
我终于决定使用 apply,我知道它更灵活。
【问题讨论】:
-
我不确定我是否理解您的输出。看看 2007 年,似乎有两个学生 Participated=yes,但你想要的输出是“3”——即所有 2007 年的学生。那么您是否希望新的 Participated 列的值成为计数?
-
.. 实际上,你的
Res1和Res2不同意这一点,所以我不确定你是否也决定了。 -
你是对的:我所说的“参与”实际上是 DataFrame 的长度(而不是参与==是)。没关系,我认为第二种解决方案看起来更有希望
-
我在Q&A 中提供了几个详细的示例和替代方法,您或其他人可能会觉得有帮助。