【问题标题】:Group dataframe by multiple columns and append the result to the dataframe按多列对数据框进行分组并将结果附加到数据框
【发布时间】:2019-02-21 16:11:45
【问题描述】:

这类似于Attach a calculated column to an existing dataframe,但是,在 pandas v0.14 中按多列分组时,该解决方案不起作用。

例如:

$ df = pd.DataFrame([
    [1, 1, 1],
    [1, 2, 1],
    [1, 2, 2],
    [1, 3, 1],
    [2, 1, 1]],
    columns=['id', 'country', 'source'])

以下计算有效:

$ df.groupby(['id','country'])['source'].apply(lambda x: x.unique().tolist())


0       [1]
1    [1, 2]
2    [1, 2]
3       [1]
4       [1]
Name: source, dtype: object

但是将输出分配给新列会导致错误:

df['source_list'] = df.groupby(['id','country'])['source'].apply(
                               lambda x: x.unique().tolist())

TypeError: 插入列的索引与框架索引不兼容

【问题讨论】:

    标签: pandas pandas-groupby


    【解决方案1】:

    将分组结果与初始 DataFrame 合并:

    >>> df1 = df.groupby(['id','country'])['source'].apply(
                 lambda x: x.tolist()).reset_index()
    
    >>> df1
      id  country      source
    0  1        1       [1.0]
    1  1        2  [1.0, 2.0]
    2  1        3       [1.0]
    3  2        1       [1.0]
    
    >>> df2 = df[['id', 'country']]
    >>> df2
      id  country
    1  1        1
    2  1        2
    3  1        2
    4  1        3
    5  2        1
    
    >>> pd.merge(df1, df2, on=['id', 'country'])
      id  country      source
    0  1        1       [1.0]
    1  1        2  [1.0, 2.0]
    2  1        2  [1.0, 2.0]
    3  1        3       [1.0]
    4  2        1       [1.0]
    

    【讨论】:

      【解决方案2】:

      避免事后合并的另一种方法是在应用于每个组的函数中提供索引,例如

      def calculate_on_group(x):
          fill_val = x.unique().tolist()
          return pd.Series([fill_val] * x.size, index=x.index)
      
      df['source_list'] = df.groupby(['id','country'])['source'].apply(calculate_on_group)
      

      【讨论】:

        【解决方案3】:

        这可以通过将groupby.apply 的结果重新分配给原始数据帧来实现,而无需合并。

        df = df.groupby(['id', 'country']).apply(lambda group: _add_sourcelist_col(group))
        

        你的 _add_sourcelist_col 函数是,

        def _add_sourcelist_col(group):
            group['source_list'] = list(set(group.tolist()))
            return group
        

        请注意,也可以在您定义的函数中添加其他列。只需将它们添加到每个组数据框,并确保在函数声明的末尾返回组。

        编辑:我会留下上面的信息,因为它可能仍然有用,但我误解了原始问题的一部分。 OP试图完成的事情可以使用,

        df = df.groupby(['id', 'country']).apply(lambda x: addsource(x))
        
        def addsource(x):
            x['source_list'] = list(set(x.source.tolist()))
            return x
        

        【讨论】:

          猜你喜欢
          • 2018-01-03
          • 2019-06-29
          • 2021-09-26
          • 2019-08-29
          • 2019-11-19
          • 2018-12-12
          • 2022-01-22
          • 2021-06-25
          • 2021-07-29
          相关资源
          最近更新 更多