【问题标题】:How to group rows, count in one column and do the sum in the other?如何对行进行分组,在一列中计数并在另一列中求和?
【发布时间】:2019-10-23 10:17:49
【问题描述】:

我想对 csv 文件的行进行分组,计算一列并添加到另一列。

例如,我想将 Commune 上的行分组以使 winner 的列与计数和列 Swing 与总和

Commune Winner Swing longitude latitude turnout
Paris   PAM    1     12.323    12.093   0.3242
Paris   PJD    0     12.323    12.093   0.1233
Paris   PAM    1     12.323    12.093   0.534
Paris   UDF    1     12.323    12.093   0.65434
Madrid  PAM    0     10.435    -3.093   0.3423
Madrid  PAM    1     10.435    -3.093   0.5234
Madrid  PJD    0     10.435    -3.093   0.235

如何对行进行分组,一列有一列,另一列有一个总和?

Commune PAM    PJD    UDF    Swing
Paris   3      1      1      3
Madrid  2      1      0      1

到目前为止我尝试过:

g = df.groupby('Commune').Winner
pd.concat([g.apply(list), g.count()], axis=1, keys=['members', 'number'])

但它返回:

    members number
Commune     
Paris   [PAM, PJD, PAM, UDF] 4
Madrid  [PAM, PAM, UDF] 3

【问题讨论】:

    标签: python python-3.x pandas pandas-groupby


    【解决方案1】:

    使用crosstab 并使用DataFrame.join 添加新列并聚合sum

    df = pd.crosstab(df['Commune'], df['Winner']).join(df.groupby('Commune')['Swing'].sum())
    print (df)
             PAM  PJD  UDF  Swing
    Commune                      
    Madrid     2    1    0      1
    Paris      2    1    1      3
    

    但如果需要行数:

    df1 = pd.crosstab(df['Commune'], df['Winner'], margins=True, margins_name='Total').iloc[:-1]
    

    或者:

    df = pd.crosstab(df['Commune'], df['Winner']).assign(Total= lambda x: x.sum(axis=1))
    

    print (df1)
    Winner   PAM  PJD  UDF  Total
    Commune                      
    Madrid     2    1    0      3
    Paris      2    1    1      4
    

    编辑:

    如果其他列可以使用 first 聚合,如果每个组的所有值和 turnout 使用其他聚合函数,如 meansum...:

    df1 = (df.groupby('Commune')
             .agg({'Swing':'sum', 'longitude':'first','latitude':'first','turnout':'mean'}))
    print (df1)
             Swing  longitude  latitude  turnout
    Commune                                     
    Madrid       1     10.435    -3.093  0.36690
    Paris        3     12.323    12.093  0.40896
    
    df = pd.crosstab(df['Commune'], df['Winner']).join(df1)
    print (df)
             PAM  PJD  UDF  Swing  longitude  latitude  turnout
    Commune                                                    
    Madrid     2    1    0      1     10.435    -3.093  0.36690
    Paris      2    1    1      3     12.323    12.093  0.40896
    

    如果想要所有没有Swing 的列中的mean 可以动态创建字典:

    d = dict.fromkeys(df.columns.difference(['Commune','Winner','Swing']), 'mean')
    d['Swing'] = 'sum'
    print (d)
    {'latitude': 'mean', 'longitude': 'mean', 'turnout': 'mean', 'Swing': 'sum'}
    
    df1 = df.groupby('Commune').agg(d)
    print (df1)
             latitude  longitude  turnout  Swing
    Commune                                     
    Madrid     -3.093     10.435  0.36690      1
    Paris      12.093     12.323  0.40896      3
    
    df = pd.crosstab(df['Commune'], df['Winner']).join(df1)
    print (df)
             PAM  PJD  UDF  latitude  longitude  turnout  Swing
    Commune                                                    
    Madrid     2    1    0    -3.093     10.435  0.36690      1
    Paris      2    1    1    12.093     12.323  0.40896      3
    

    【讨论】:

    • 非常感谢!我喜欢你真正可读的答案。如果我有其他列,我怎么能保留它们?而且,为了防止任何列名冲突,如何将结果存储在不同的名称下?喜欢PAM_sum
    • @IggyPass - 你能更具体一点吗?如何处理其他列?通过聚合?或者喜欢crosstab
    • 当然!我已经更新了一些数据集。假设我有一列包含每个城市的纬度和对数,另一列包含我想要保留的投票率,以保存信息,作为聚合行的平均值
    【解决方案2】:

    应该这样做:

    pd.pivot_table(df, values='Swing', index='Commune', columns='Winner', aggfunc='count').fillna(0).join(df.groupby('Commune')['Swing'].sum())
    
    #         PAM  PJD  UDF  Swing
    #Commune                      
    #Madrid   2.0  1.0  0.0      1
    #Paris    2.0  1.0  1.0      3
    

    【讨论】:

    • 非常感谢!我喜欢你非常简洁的回答。如果我有其他列,我怎么能保留它们?而且,为了防止任何列名冲突,如何将结果存储在不同的名称下,同时尽可能取其他名称的平均值?
    【解决方案3】:

    我就是这样做的。

    df_a = pd.pivot_table(df, values='Swing', index='Commune', columns='Winner', aggfunc='count', fill_value =0)
    df_b = df.groupby('Commune')[['Swing']].sum()
    output_df = df_a.join(df_b)
    

    【讨论】:

      猜你喜欢
      • 2018-05-22
      • 2014-10-20
      • 2020-08-21
      • 1970-01-01
      • 2021-04-29
      • 1970-01-01
      • 1970-01-01
      • 2021-10-30
      • 1970-01-01
      相关资源
      最近更新 更多