【问题标题】:Pandas perform operation over grouped dataPandas 对分组数据执行操作
【发布时间】:2017-03-17 11:52:32
【问题描述】:

我想对 pandas 数据框中的分组数据执行一个函数。 我有下面的 df 并迭代地执行以下操作,但认为这应该由 pandas groupby 完成。

import pandas as pd
import scipy
from scipy.stats import mstats 

df = pd.DataFrame({'cfs': [147248, 94894, 81792, 176011, 208514, 18111, 56742, 154900, 32778, 142333, 45267, 145211, 3429, 1258, 65439], 'Alternatives':['A','B','C']*5})

alternatives = list(set(df['Alternatives']))

df2 = pd.DataFrame()

for alternative in alternatives:
    alt = pd.DataFrame(df[(df.Alternatives == alternative)])
    alt = alt.sort_values(['cfs'])
    alt['rank'] = alt['cfs'].rank()
    alt['pp'] = 1 - scipy.stats.mstats.plotting_positions(alt['cfs'],0,0) 
    df2 = df2.append(alt) 

输出:

Alternatives     cfs  rank        pp
12            A    3429   1.0  0.833333
6             A   56742   2.0  0.666667
9             A  142333   3.0  0.500000
0             A  147248   4.0  0.333333
3             A  176011   5.0  0.166667
5             C   18111   1.0  0.833333
8             C   32778   2.0  0.666667
14            C   65439   3.0  0.500000
2             C   81792   4.0  0.333333
11            C  145211   5.0  0.166667
13            B    1258   1.0  0.833333
10            B   45267   2.0  0.666667
1             B   94894   3.0  0.500000
7             B  154900   4.0  0.333333
4             B  208514   5.0  0.166667

我可以通过

获得排名
df['rank'] = df['cfs'].groupby(df['Alternatives']).rank()

但我无法获得绘图位置。我最接近的是:

group = df['cfs'].groupby(df['Alternatives']).apply(scipy.stats.mstats.plotting_positions,0,0 ) 

这给了我一个带有正确数据的熊猫系列,但我想做的是:

df['pp'] = df['cfs'].groupby(df['Alternatives']).apply(scipy.stats.mstats.plotting_positions,0,0)  

但是,这只是返回一列 NaN

谢谢

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:
    def func(x):
        x['pp'] = 1 - scipy.stats.mstats.plotting_positions(x.cfs, 0, 0)
        return x
    
    df.groupby('Alternatives').apply(func)
    
       Alternatives     cfs        pp
    0             A  147248  0.333333
    1             B   94894  0.500000
    2             C   81792  0.333333
    3             A  176011  0.166667
    4             B  208514  0.166667
    5             C   18111  0.833333
    6             A   56742  0.666667
    7             B  154900  0.333333
    8             C   32778  0.666667
    9             A  142333  0.500000
    10            B   45267  0.666667
    11            C  145211  0.166667
    12            A    3429  0.833333
    13            B    1258  0.833333
    14            C   65439  0.500000
    

    有助于调试groupby的是使用get_group

    g = df.groupby('Alternatives').get_group('A')
    g.apply(whatever)  # test on a single group and then apply to all at once
    

    【讨论】:

    • 听从您的建议,为什么g = df.groupby('Alternatives').get_group('A')g.sort_values('rank') 有效,而df.groupby('Alternatives').sort_values('rank') 无效? def func(x): x.sort_values('rank') return x df.groupby('Alternatives').apply(func) 也没有。感谢您的帮助,只是觉得 gb 应该更容易应用操作。
    • @JeffTilton 第二个变体非常接近工作,问题是sort_values 返回一个新的数据帧。试试def func(x): return x.sort_values('rank') 或单线df.groupby('Alternatives').apply(lambda df: df.sort_values('rank'))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 2022-01-12
    • 2018-06-14
    • 1970-01-01
    • 2017-09-02
    • 2018-11-28
    相关资源
    最近更新 更多