【问题标题】:Pandas dataframe how to make element-wise mean of list columns熊猫数据框如何使列表列的元素均值
【发布时间】:2021-08-12 12:23:22
【问题描述】:

我有一个具有分类特征和价值特征的数据框。 值特征始终是具有完全相同大小的列表(例如 3)。 所以数据框是:

Sub Model iter key     l1       l2     l3
 01  b     0    0    [8,8,5] [3,8,1] [6,7,8]
 01  b     1    1    [4,3,6] [3,4,0] [4,0,4]
 01  b     2    2    [0,1,4] [0,0,5] [8,2,3]
 03  b     3    0    [1,8,2] [4,6,0] [1,3,9]
 03  b     4    1    [7,3,1] [6,8,1] [6,7,9]
 03  b     5    2    [1,1,0] [11,4,8] [8,5,9]

我想按[sub,model] 对数据框进行分组,这样在每一行中,我将对列键的值取平均值。 所以我会得到:

Sub  Model     l1         l2       l3 
 01   b      [4, 4, 5]  [2,2,2]   [6,3,5]
 03   b      [3, 4, 1]  [7,6,3]   [3,5,9]

最好的方法是什么?

【问题讨论】:

    标签: python pandas dataframe pandas-groupby data-munging


    【解决方案1】:

    您可以使用agg 和自定义函数:

    def mean_list(sr):
        return sr.apply(pd.Series).mean()
    
    out = df.groupby(['Sub', 'Model'])[['l1', 'l2', 'l3']].agg(mean_list)
    
    >>> out
                            l1               l2               l3
    Sub Model
    01  b      [4.0, 4.0, 5.0]  [2.0, 4.0, 2.0]  [6.0, 3.0, 5.0]
    03  b      [3.0, 4.0, 1.0]  [7.0, 6.0, 3.0]  [5.0, 5.0, 9.0]
    

    【讨论】:

    • 你错过了' ;) +1 我一直喜欢自定义函数
    • @Corralien 我收到错误 {ValueError}Function does not reduce ,知道为什么吗?
    • 用您的真实数据框样本更新您的帖子。
    【解决方案2】:

    你可以使用下面的sn-p:

    (df.groupby(['Sub', 'Model'])
       [['l1', 'l2', 'l3']]
       .apply(lambda d: pd.Series({c: np.array([*d[c].values]).mean(0)
                                   for c in d.columns}))
    )
    

    输出:

                            l1               l2               l3
    Sub Model                                                   
    01  b      [4.0, 4.0, 5.0]  [2.0, 4.0, 2.0]  [6.0, 3.0, 5.0]
    03  b      [3.0, 4.0, 1.0]  [7.0, 6.0, 3.0]  [5.0, 5.0, 9.0]
    

    【讨论】:

      【解决方案3】:

      您可以将.groupby() + .agg() 与np.mean() 一起使用,如下所示:

      import numpy as np
      
      (df.groupby(['Sub', 'Model'])[['l1', 'l2', 'l3']]
         .agg(lambda x: np.mean(x.values.tolist(), axis=0)).reset_index()
      )
      

      结果:

        Sub Model               l1               l2               l3
      0  01     b  [4.0, 4.0, 5.0]  [2.0, 4.0, 2.0]  [6.0, 3.0, 5.0]
      1  03     b  [3.0, 4.0, 1.0]  [7.0, 6.0, 3.0]  [5.0, 5.0, 9.0]
      

      编辑:

      如果您的l1、l2、l3 实际上是字符串,看起来像列表,您可以在解决方案代码之前执行以下操作:

      df['l1'] = df['l1'].str.strip('[]').str.split(',', expand=True).astype(int).apply(lambda x: list(x), axis=1)
      df['l2'] = df['l2'].str.strip('[]').str.split(',', expand=True).astype(int).apply(lambda x: list(x), axis=1)
      df['l3'] = df['l3'].str.strip('[]').str.split(',', expand=True).astype(int).apply(lambda x: list(x), axis=1)
      

      【讨论】:

      • 我得到错误 {ValueError}Function does not reduce ,知道为什么吗?
      • @okuoub 列表是真实的列表还是字符串看起来像 list ?您可以将df.to_dict() 输出发布到问题中吗?
      • @okuoub 查看我的编辑代码,将看起来像列表的字符串转换为真实列表。你可以试试看。
      猜你喜欢
      • 2021-07-21
      • 1970-01-01
      • 2018-10-23
      • 2019-12-02
      • 1970-01-01
      • 1970-01-01
      • 2018-03-06
      • 2019-02-12
      相关资源
      最近更新 更多