在多索引级别上应用带有参数的函数

时间:2018-07-30 06:42:23

标签: pandas pandas-groupby multi-index

我想将自定义函数应用于multiindex中的每个级别。 例如,我有数据框

df = pd.DataFrame(np.arange(16).reshape((4,4)),
               columns=pd.MultiIndex.from_product([['OP','PK'],['PRICE','QTY']]))

我想为每个级别0的列添加一列,称为“值”,它是以下函数的结果;

def my_func(df, scale):
     return df['QTY']*df['PRICE']*scale

用户在其中提供“比例”值的地方。

即使设置此示例,我也不确定如何显示所需的结果。但我知道我希望最终数据框的multiindex列为

pd.DataFrame(columns=pd.MultiIndex.from_product([['OP','PK'],['PRICE','QTY','Value']]))

即使那还不够,我想为“ OP” 0级列应用一个“标度”值,为“ PK”列应用一个不同的“标度”值。

2 个答案:

答案 0 :(得分:1)

使用:

def my_func(df, scale):
     #select second level of columns
     df1 = df.xs('QTY', axis=1, level=1).values *df.xs('PRICE', axis=1, level=1) * scale
     #create MultiIndex in columns 
     df1.columns = pd.MultiIndex.from_product([df1.columns, ['val']])
     #join to original
     return pd.concat([df, df1], axis=1).sort_index(axis=1)

print (my_func(df, 10))
     OP              PK          
  PRICE QTY   val PRICE QTY   val
0     0   1     0     2   3    60
1     4   5   200     6   7   420
2     8   9   720    10  11  1100
3    12  13  1560    14  15  2100

编辑:

对于多个按比例缩放的值,每个级别都可以使用不同的值列表:

print (my_func(df, [10, 20]))

     OP              PK          
  PRICE QTY   val PRICE QTY   val
0     0   1     0     2   3   120
1     4   5   200     6   7   840
2     8   9   720    10  11  2200
3    12  13  1560    14  15  4200

答案 1 :(得分:1)

使用groupby + agg,然后将片段与pd.concat串联在一起。

scale = 10
v = df.groupby(level=0, axis=1).agg(lambda x: x.values.prod(1) * scale) 
v.columns = pd.MultiIndex.from_product([v.columns, ['value']])

pd.concat([df, v], axis=1).sort_index(axis=1, level=0)

     OP              PK          
  PRICE QTY value PRICE QTY value
0     0   1     0     2   3    60
1     4   5   200     6   7   420
2     8   9   720    10  11  1100
3    12  13  1560    14  15  2100