Pandas 基于级别为 1 的 groupby 创建百分位数字段
Pandas create percentile field based on groupby with level 1
给定以下数据框:
import pandas as pd
df = pd.DataFrame({
('Group', 'group'): ['a','a','a','b','b','b'],
('sum', 'sum'): [234, 234,544,7,332,766]
})
我想创建一个新字段,用于计算 "group" 中每组 "sum" 每个值的百分位数。问题是,我有 2 header 列,无法弄清楚如何避免出现错误:
ValueError: level > 0 only valid with MultiIndex
当我运行这个:
df=df.groupby('Group',level=1).sum.rank(pct=True, ascending=False)
我需要将 header 保持在相同的结构中。
提前致谢!
要按第一列 ('Group', 'group')
分组并计算 ('sum', 'sum')
列的排名,请使用:
In [106]: df['rank'] = (df[('sum', 'sum')].groupby(df[('Group', 'group')]).rank(pct=True, ascending=False))
In [107]: df
Out[107]:
Group sum rank
group sum
0 a 234 0.833333
1 a 234 0.833333
2 a 544 0.333333
3 b 7 1.000000
4 b 332 0.666667
5 b 766 0.333333
请注意,.rank(pct=True)
计算的是 百分比 排名,而不是 百分位数 。要计算百分位数,您可以使用 scipy.stats.percentileofscore
.
import scipy.stats as stats
df['percentile'] = (df[('sum', 'sum')].groupby(df[('Group', 'group')])
.apply(lambda ser: 100-pd.Series([stats.percentileofscore(ser, x, kind='rank')
for x in ser], index=ser.index)))
产量
Group sum rank percentile
group sum
0 a 234 0.833333 50.000000
1 a 234 0.833333 50.000000
2 a 544 0.333333 0.000000
3 b 7 1.000000 66.666667
4 b 332 0.666667 33.333333
5 b 766 0.333333 0.000000
给定以下数据框:
import pandas as pd
df = pd.DataFrame({
('Group', 'group'): ['a','a','a','b','b','b'],
('sum', 'sum'): [234, 234,544,7,332,766]
})
我想创建一个新字段,用于计算 "group" 中每组 "sum" 每个值的百分位数。问题是,我有 2 header 列,无法弄清楚如何避免出现错误:
ValueError: level > 0 only valid with MultiIndex
当我运行这个:
df=df.groupby('Group',level=1).sum.rank(pct=True, ascending=False)
我需要将 header 保持在相同的结构中。
提前致谢!
要按第一列 ('Group', 'group')
分组并计算 ('sum', 'sum')
列的排名,请使用:
In [106]: df['rank'] = (df[('sum', 'sum')].groupby(df[('Group', 'group')]).rank(pct=True, ascending=False))
In [107]: df
Out[107]:
Group sum rank
group sum
0 a 234 0.833333
1 a 234 0.833333
2 a 544 0.333333
3 b 7 1.000000
4 b 332 0.666667
5 b 766 0.333333
请注意,.rank(pct=True)
计算的是 百分比 排名,而不是 百分位数 。要计算百分位数,您可以使用 scipy.stats.percentileofscore
.
import scipy.stats as stats
df['percentile'] = (df[('sum', 'sum')].groupby(df[('Group', 'group')])
.apply(lambda ser: 100-pd.Series([stats.percentileofscore(ser, x, kind='rank')
for x in ser], index=ser.index)))
产量
Group sum rank percentile
group sum
0 a 234 0.833333 50.000000
1 a 234 0.833333 50.000000
2 a 544 0.333333 0.000000
3 b 7 1.000000 66.666667
4 b 332 0.666667 33.333333
5 b 766 0.333333 0.000000