如何用PythonPandas聚合、获取百分比、重新分配列和行?
How to aggregate, obtain percentage, and reassign column and row with Python Pandas?
我有三列 Decision 作为 A(接受)和 D(拒绝),以及年份和月份
Decision Year Month
A 2003 1
A 2005 3
D 2005 2
D 2003 3
A 2004 1
我想根据 decision='A' 的计数对其进行重组,然后制作一个新的 df,以 Year 为索引,以每个月为列。注意:现在每个单元格都变成了编号。该年月'A'
Year Month1 Month2 Month3 ...
2002 1 3 4
2003 2 4 5
2004 2 3 5
2005 5 3 42
2006 4 2 12
同样,我想要另一个 df 用于决策='D'
Year Month1 Month2 Month3 ...
2002 4 4 3
2003 2 4 23
2004 4 1 12
2005 4 2 31
2006 4 2 22
但最终,我希望每个单元格都是 (no. 'A')/(no. 'A' + no. 'D')
的百分比
Year Month1 Month2 Month3 ...
2002 .2 .43 .57
2003 (etc)
2004 (etc)
2005 (etc)
2006 (etc)
我尝试使用 pandas 的 groupby 但没有成功,我想我可以创建不同的列表来获取计数然后将列表合并在一起以创建 df,但我想知道 Pandas 是否有一些东西更简单。
在 groupby
内使用 value_counts
使用 normalize=True
d1 = df.groupby(['Year', 'Month']).Decision.value_counts(normalize=True)
d1.xs('A', level='Decision').unstack('Month', fill_value=0).add_prefix('Month')
Month Month1 Month2 Month3
Year
2002 0.200000 0.428571 0.571429
2003 0.400000 0.666667 0.416667
2004 0.285714 0.300000 0.312500
设置
df = pd.DataFrame(dict(
Decision=['A'] * 29 + ['D'] * 46,
Year=[2002] * 8 + [2003] * 11 + [2004] * 10
+ [2002] * 11 + [2003] * 12 + [2004] * 23,
Month=[
1, 2, 2, 2, 3, 3, 3, 3, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3,
1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3,
3, 3, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
))[['Decision', 'Year', 'Month']]
这将在不构建 2 个中间 DF 的情况下为您提供最终结果。
#use groupby, count As and get percentage, finally pivot month to columns.
df.groupby(by=['Year','Month'])['Decision'].apply(lambda x: len(x[x=='A'])/float(len(x))).reset_index(level=1).pivot(columns='Month').fillna(0)
Out[257]:
Decision
Month 1 2 3
Year
2003 1.0 0.0 0.0
2004 1.0 0.0 0.0
2005 0.0 0.0 1.0
我有三列 Decision 作为 A(接受)和 D(拒绝),以及年份和月份
Decision Year Month
A 2003 1
A 2005 3
D 2005 2
D 2003 3
A 2004 1
我想根据 decision='A' 的计数对其进行重组,然后制作一个新的 df,以 Year 为索引,以每个月为列。注意:现在每个单元格都变成了编号。该年月'A'
Year Month1 Month2 Month3 ...
2002 1 3 4
2003 2 4 5
2004 2 3 5
2005 5 3 42
2006 4 2 12
同样,我想要另一个 df 用于决策='D'
Year Month1 Month2 Month3 ...
2002 4 4 3
2003 2 4 23
2004 4 1 12
2005 4 2 31
2006 4 2 22
但最终,我希望每个单元格都是 (no. 'A')/(no. 'A' + no. 'D')
的百分比Year Month1 Month2 Month3 ...
2002 .2 .43 .57
2003 (etc)
2004 (etc)
2005 (etc)
2006 (etc)
我尝试使用 pandas 的 groupby 但没有成功,我想我可以创建不同的列表来获取计数然后将列表合并在一起以创建 df,但我想知道 Pandas 是否有一些东西更简单。
在 groupby
内使用 value_counts
使用 normalize=True
d1 = df.groupby(['Year', 'Month']).Decision.value_counts(normalize=True)
d1.xs('A', level='Decision').unstack('Month', fill_value=0).add_prefix('Month')
Month Month1 Month2 Month3
Year
2002 0.200000 0.428571 0.571429
2003 0.400000 0.666667 0.416667
2004 0.285714 0.300000 0.312500
设置
df = pd.DataFrame(dict(
Decision=['A'] * 29 + ['D'] * 46,
Year=[2002] * 8 + [2003] * 11 + [2004] * 10
+ [2002] * 11 + [2003] * 12 + [2004] * 23,
Month=[
1, 2, 2, 2, 3, 3, 3, 3, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3,
1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3,
3, 3, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
))[['Decision', 'Year', 'Month']]
这将在不构建 2 个中间 DF 的情况下为您提供最终结果。
#use groupby, count As and get percentage, finally pivot month to columns.
df.groupby(by=['Year','Month'])['Decision'].apply(lambda x: len(x[x=='A'])/float(len(x))).reset_index(level=1).pivot(columns='Month').fillna(0)
Out[257]:
Decision
Month 1 2 3
Year
2003 1.0 0.0 0.0
2004 1.0 0.0 0.0
2005 0.0 0.0 1.0