【问题标题】:concise way of flattening multiindex columns扁平化多索引列的简洁方法
【发布时间】:2018-11-07 08:49:12
【问题描述】:

在 groupby-aggregate 中使用超过 1 个函数会导致多索引,然后我想将其展平。

示例:

df = pd.DataFrame(
    {'A': [1,1,1,2,2,2,3,3,3],
     'B': np.random.random(9),
     'C': np.random.random(9)}
)
out = df.groupby('A').agg({'B': [np.mean, np.std], 'C': np.median})

# example output

          B                   C
       mean       std    median
A
1  0.791846  0.091657  0.394167
2  0.156290  0.202142  0.453871
3  0.482282  0.382391  0.892514

目前,我是这样手动完成的

out.columns = ['B_mean', 'B_std', 'C_median']

这给了我想要的结果

     B_mean     B_std  C_median
A
1  0.791846  0.091657  0.394167
2  0.156290  0.202142  0.453871
3  0.482282  0.382391  0.892514

但我正在寻找一种方法来自动化这个过程,因为这很单调、耗时,并且允许我在重命名列时出现拼写错误。

在进行分组聚合时,有没有办法返回扁平索引而不是多索引?

我需要展平列以保存到文本文件,然后由不处理多索引列的不同程序读取。

【问题讨论】:

    标签: pandas pandas-groupby


    【解决方案1】:

    你可以使用:

    out.columns = list(map('_'.join, out.columns.values))
    

    【讨论】:

      【解决方案2】:

      您可以使用列进行map join

      out.columns = out.columns.map('_'.join)
      out
      Out[23]: 
           B_mean     B_std  C_median
      A                              
      1  0.204825  0.169408  0.926347
      2  0.362184  0.404272  0.224119
      3  0.533502  0.380614  0.218105
      

      出于某种原因(当列包含 int 时)我更喜欢这种方式

      out.columns.map('{0[0]}_{0[1]}'.format) 
      Out[27]: Index(['B_mean', 'B_std', 'C_median'], dtype='object')
      

      【讨论】:

        【解决方案3】:

        从 0.24.0 版本开始,您可以只使用 to_flat_index

        out.columns = [f"{x}_{y}" for x, y in out.columns.to_flat_index()]
        
            B_mean      B_std       C_median
        A           
        1   0.779592    0.137168    0.583211
        2   0.158010    0.229234    0.550383
        3   0.186771    0.150575    0.313409
        

        【讨论】:

          【解决方案4】:

          在其他答案的基础上:如果其中一列在第二级未命名,则会在列名后面加上反斜杠(例如 D_)。

          为防止这种情况,请使用 lambda 函数:

          out.columns = out.columns.map(lambda x: '_'.join(a for a in x if len(a)>0))
          

          【讨论】:

            【解决方案5】:

            我编写了一个猴子可修补函数来扁平化来自 .agg 的列,就像这样,它使用 .join 但做了一些检查以避免像 col_ 这样的列名。

            def flatten_columns(self):
                """Monkey patchable function onto pandas dataframes to flatten MultiIndex column names.
            
                pd.DataFrame.flatten_columns = flatten_columns
                """
                df = self.copy()
                df.columns = [
                    '_'.join([str(x)
                              for x in [y for y in item
                                        if y]]) if not isinstance(item, str) else item
                    for item in df.columns
                ]
                return df
            

            那么在你原来的例子中,用这个函数修补到DataFrame 可以:

            df = pd.DataFrame(
                {'A': [1,1,1,2,2,2,3,3,3],
                 'B': np.random.random(9),
                 'C': np.random.random(9)}
            )
            out = df.groupby('A').agg({'B': [np.mean, np.std], 'C': np.median}).flatten_columns()
            
            #example flattened output
            
                 B_mean     B_std  C_median
            A                              
            1  0.534301  0.168850  0.009058
            2  0.547040  0.213936  0.575277
            3  0.640177  0.250562  0.456109
            

            【讨论】:

              猜你喜欢
              • 2021-02-03
              • 2019-02-18
              • 2021-08-22
              • 2019-12-07
              • 2018-05-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多