【问题标题】:pandas groupby and join lists熊猫 groupby 和加入列表
【发布时间】:2021-05-12 23:02:42
【问题描述】:

我有一个数据框 df,有两列,我想按一列分组并加入属于同一组的列表,例如:

column_a, column_b
1,         [1,2,3]
1,         [2,5]
2,         [5,6]

处理后:

column_a, column_b
1,         [1,2,3,2,5]
2,         [5,6]

我想保留所有重复项。我有以下问题:

  • 数据框的 dtypes 是对象。 convert_objects() 不会自动将 column_b 转换为列表。我怎样才能做到这一点?
  • df.groupby(...).apply(lambda x: ...) 中的函数适用于什么? x 的形式是什么?列表?
  • 我的主要问题的解决方案?

提前致谢。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    object dtype 是一个包罗万象的 dtype,基本上意味着不是 int、float、bool、datetime 或 timedelta。所以它将它们存储为一个列表。 convert_objects 尝试将列转换为其中一种数据类型。

    你想要

    In [63]: df
    Out[63]: 
       a          b    c
    0  1  [1, 2, 3]  foo
    1  1     [2, 5]  bar
    2  2     [5, 6]  baz
    
    
    In [64]: df.groupby('a').agg({'b': 'sum', 'c': lambda x: ' '.join(x)})
    Out[64]: 
             c                b
    a                          
    1  foo bar  [1, 2, 3, 2, 5]
    2      baz           [5, 6]
    

    这将按列a 中的值对数据框进行分组。阅读有关groupby 的更多信息。

    这是一个常规列表sum(连接),就像[1, 2, 3] + [2, 5] 一样,结果是[1, 2, 3, 2, 5]

    【讨论】:

    • 谢谢,我还有一个问题:如果我有第三列是字符串类型,我想' '。按列的组加入它们。我该怎么办?
    • 字符串就像字符列表。所以.sum() 也应该在那里工作。
    • 是的,但我希望在每个连接的字符串之间有一个 ' '(空格)。
    • 希望我能多点赞,谢谢!该 lambda 函数应用于列表? ['foo'、'bar'] 和 ['baz'] ?
    • 为什么不只是'c': ' '.join
    【解决方案2】:
    df.groupby('column_a').agg(sum)
    

    这是因为运算符重载sum 将列表连接在一起。结果df的索引将是来自column_a的值:

    【讨论】:

    • 不错的解决方案(7 年后实现)。一个推论的观察:当summing up 同时列出个数字时,单个.agg(sum) 只对数字列求和。在这种情况下,字典 {'a': sum, 'b': sum} --thanks @TomAugspurger-- 完美!
    【解决方案3】:

    上面提出的使用df.groupby('column_a').agg(sum) 的方法确实有效。但是,您必须确保您的列表只包含integers,否则输出将不一样。

    如果要将所有列表项转换为整数,可以使用:

    df['column_a'] = df['column_a'].apply(lambda x: list(map(int, x)))
    

    【讨论】:

      【解决方案4】:

      使用 numpy 和简单的“for”或“map”:

      import numpy as np

      u_clm = np.unique(df.column_a.values)
      all_lists = []
      
      for clm in u_clm:
          df_process = df.query('column_a == @clm')
          list_ = np.concatenate(df.column_b.values)
          all_lists.append((clm, list_.tolist()))
      

      df_sum_lists = pd.DataFrame(all_lists)

      对于大型数据集,它比简单的“groupby-agg-sum”方法快 350 倍。

      【讨论】:

        猜你喜欢
        • 2022-06-14
        • 1970-01-01
        • 2019-04-12
        • 2018-09-18
        • 2021-06-16
        • 2013-10-24
        • 2013-06-06
        • 2019-01-18
        • 2020-09-08
        相关资源
        最近更新 更多