Python 3.x 利用apply降低多索引数据帧的维数

Python 3.x 利用apply降低多索引数据帧的维数,python-3.x,pandas,dataframe,pandas-groupby,pandas-apply,Python 3.x,Pandas,Dataframe,Pandas Groupby,Pandas Apply,我有以下数据帧: df = pd.DataFrame({('psl', 't1'): {'fiat': 36.389809173765507, 'mazda': 18.139242981049016, 'opel': 0.97626485600703961, 'toyota': 74.464422292108878}, ('psl', 't2'): {'fiat': 35.423004380643462, 'mazda': 24.269803148695079, 'opel

我有以下数据帧:

df = pd.DataFrame({('psl', 't1'): {'fiat': 36.389809173765507,
  'mazda': 18.139242981049016,
  'opel': 0.97626485600703961,
  'toyota': 74.464422292108878},
 ('psl', 't2'): {'fiat': 35.423004380643462,
  'mazda': 24.269803148695079,
  'opel': 1.0170540474994665,
  'toyota': 60.389948228586832},
 ('psv', 't1'): {'fiat': 35.836800462163097,
  'mazda': 15.893295606055901,
  'opel': 0.78744853046848606,
  'toyota': 74.054850828062271},
 ('psv', 't2'): {'fiat': 34.379812557124815,
  'mazda': 23.202587247335682,
  'opel': 0.80191294532382451,
  'toyota': 58.735083244244322}})
看起来是这样的:

我想把它从一个多索引减少到一个普通索引。我希望通过应用一个使用t1和t2值的函数,并只返回一个值,这将导致出现两列:psl和psv

我已成功地将其分组并应用一个函数:

df.groupby(level=0, axis=1).agg(np.mean) 
这与我想要的非常接近,只是我不想应用np.mean,而是一个自定义函数。特别是百分比变化函数

我的最终目标是能够做这样的事情:

df.groupby(level=0, axis=1).apply(lambda t1, t2: (t2-t1)/t1)
将返回此错误:

TypeError: <lambda>() missing 1 required positional argument: 't2'
这反过来又返回:

KeyError: (('psl', 't1'), 'occurred at index (psl, t1)')

请你尽你最大的能力对你的答案的每一部分都做一个透彻的解释,这样我才能更好地理解熊猫是如何工作的。

不容易。使用自定义函数for
系列
和for选择列中的
多索引

def f(x):
    t2 = x.xs('t2', axis=1, level=1)
    t1 = x.xs('t1', axis=1, level=1)
    a = (t2-t1)/t1
    #print (a)
    return (a.squeeze())

df1 = df.groupby(level=0, axis=1).agg(f) 
print (df1)
             psl       psv
fiat   -0.026568 -0.040656
mazda   0.337972  0.459898
opel    0.041781  0.018369
toyota -0.189009 -0.206871
使用lambda函数是可能的,但重复代码非常多:

df1 = df.groupby(level=0, axis=1)
        .agg(lambda x: ((x.xs('t2', axis=1, level=1)-x.xs('t1', axis=1, level=1))/
                                 x.xs('t1', axis=1, level=1)).squeeze()) 
df1 = df.groupby(level=0, axis=1)
        .agg(lambda x: ((x.xs('t2', axis=1, level=1)-x.xs('t1', axis=1, level=1))/
                                 x.xs('t1', axis=1, level=1)).squeeze())