转换多索引数据框以保留groupby()聚合

时间:2018-08-13 09:01:06

标签: python pandas dataframe multi-index

问题:

我的数据框有多个列,其中包含按品牌分组的某些产品的信息。每个产品在第1列,第2列等中都有一些属性。这些列分别捕获子列min,max和all中的其他信息。分组的方式是,品牌和模型形成数据框的多索引

                          column 1       column 2      column 3      
brand       model         min max all    min max all   min max all    min max all

brand(1)    model(1)
            model(2)
            model(3)

brand(2)    model(1)    
  .         model(2) 
  .         model(3)
  .           .
brand(n)    

我需要向此数据帧添加一个称为列4的新列,该列需要拥有相同的子列minmaxall,并且必须是数据帧的长度。 / p>

尝试:

以下代码使用列new_column及其相应的子列minmaxall创建具有原始数据帧长度的数据帧。

columns_to_add = pd.DataFrame(index= range(len(original_df.index)), columns =  ["new_column","new_column","new_column"],["min","max","all"]])
original_df = original_df.append(columns_to_add)

但是,当我可视化原始数据框时,似乎我失去了最初的分组并得到了类似的内容。

                          column 1      column 2       column 3     new_column
                          min max all   min max all  min max all    min max all

(brand(1),model(1))
(brand(1),model(2))
(brand(1),model(3))

(brand(2),model(1))    
(brand(2),model(2))
(brand(2),model(3))
         .          
         .          
(brand(n),model(i))
         .           
 1410                     NaN NaN NaN   NaN NaN NaN   NaN NaN NaN   
 1411                     NaN NaN NaN   NaN NaN NaN   NaN NaN NaN                          
 1412                     NaN NaN NaN   NaN NaN NaN   NaN NaN NaN     

我不知道这些从1410开始的多余行来自何处​​。我相信取消分组是造成这种情况的原因,因此这些行用NaN填充。

问题:

  1. 我是否可以通过这种方式添加new_column来保留分组?
  2. 对于这些用NaN填充的新行,我该怎么办?

编辑:

[1] 我刚刚意识到我的原始数据帧有1440行,而包含空行的新数据帧长2880行,换句话说,是原始数据帧的长度的两倍。是什么导致行增加一倍?

[2] 如何在多索引数据帧上执行transform()以保持分组依据?这样可以防止数据框的行数加倍

1 个答案:

答案 0 :(得分:1)

要回答您的主要问题,可以使用MultiIndex.from_product添加带有子列的新多级列。一些测试数据来说明该过程:

df = pd.DataFrame({'brand': [1,1,1,1,2,2,2,2], 'model': [3,3,4,4,5,5,5,6], 'col1': [1,2,3,4,5,6,7,8], 'col2': [9,8,7,6,5,4,3,2]})
df = df.groupby(['brand', 'model']).agg({'col1': ['min', 'max', 'mean'], 'col2': ['min', 'max', 'mean']})

给出:

                col1          col2
            min max mean  min max mean
brand model                     
1     3     1   2   1.5   8   9   8.5  
      4     3   4   3.5   6   7   6.5
2     5     5   7   6.0   3   5   4.0
      6     8   8   8.0   2   2   2.0

添加新的多级列:

df = df.join(pd.DataFrame(np.random.rand(len(df),3),
                          columns=pd.MultiIndex.from_product([['new_column'], ['min','max','mean']]),
                          index=df.index))

此处使用np.random.rand(len(df),3)来填充值,但是只要尺寸正确即可使用任何东西。在此不使用任何值会将新列中的值设置为NaN

结果:

                col1          col2            new_column
            min max mean  min max mean  min      max      mean
brand model                     
1     3     1   2   1.5   8   9   8.5   0.065094 0.489666 0.476452
      4     3   4   3.5   6   7   6.5   0.280267 0.237083 0.272776
2     5     5   7   6.0   3   5   4.0   0.650988 0.384788 0.486176
      6     8   8   8.0   2   2   2.0   0.025630 0.908280 0.386871