如何使用MultiIndex在单个级别的DataFrame上迭代和应用函数?

Tim*_*omb 5 python pandas

感谢对我最初的问题的回复,我现在有了一个多索引的DataFrame,就像我想要的那样.现在我已经掌握了数据结构的数据,我试图将其解决,并想知道是否有更好的方法来实现这一点.我的两个问题是相关的,但可能有单独的"理想"解决方案:

示例DataFrame(截断)

Experiment           IWWGCW         IWWGDW       
Lead Time                24     48      24     48
2010-11-27 12:00:00   0.997  0.991   0.998  0.990
2010-11-28 12:00:00   0.998  0.987   0.997  0.990
2010-11-29 12:00:00   0.997  0.992   0.997  0.992
2010-11-30 12:00:00   0.997  0.987   0.997  0.987
2010-12-01 12:00:00   0.996  0.986   0.996  0.986
Run Code Online (Sandbox Code Playgroud)

迭代

我希望能够循环遍历这个DataFrame,其中迭代只会使我只有1个索引维度,即一个iteritems将返回[('IWWGCW', df['IWWGCW']), ('IWWGDW', df['IWWGDW'])]并产生带有提前时间列的2个DataFrame 的行为.我的暴力解决方案是使用基本上做的包装程序[(key, df[key] for key in df.columns.levels[0]].有一个更好的方法吗?

应用

我还想做一些事情,比如"从其他人那里减去IWWGDW条目"来计算配对差异.我试着做df.apply(lambda f: f - df['IWWGDW'])KeyError: ('IWWGDW', 'occurred at index 2010-11-26 12:00:00')不管我是否使用axis=1或得到axis=0.我尝试使用上面提到的迭代解决方法重建一个新的DataFrame,但是当我暴力破解时我总是担心.是否有更"残酷"的方式来进行这种计算?

Wes*_*ney 6

我建议使用groupby进行迭代:

In [25]: for exp, group in df.groupby(level=0, axis=1):
   ....:     print exp, group
   ....:     
IWWGCW Experiment           IWWGCW       
Lead Time                24     48
2010-11-27 12:00:00   0.997  0.991
2010-11-28 12:00:00   0.998  0.987
2010-11-29 12:00:00   0.997  0.992
2010-11-30 12:00:00   0.997  0.987
2010-12-01 12:00:00   0.996  0.986
IWWGDW Experiment           IWWGDW       
Lead Time                24     48
2010-11-27 12:00:00   0.998  0.990
2010-11-28 12:00:00   0.997  0.990
2010-11-29 12:00:00   0.997  0.992
2010-11-30 12:00:00   0.997  0.987
2010-12-01 12:00:00   0.996  0.986
Run Code Online (Sandbox Code Playgroud)

但是,我发现这并没有像你想要的那样降低顶级水平.理想情况下,您可以编写如下内容:

df.groupby(level=0, axis=1).sub(df['IWWGCW'])

并且具有成对减法,但由于df['IWWGCW']降低了级别,列名称不对齐.但这有效:

In [29]: df.groupby(level=0, axis=1).sub(df['IWWGCW'].values)
Out[29]: 
Experiment           IWWGCW      IWWGDW       
Lead Time                24  48      24     48
2010-11-27 12:00:00       0   0   0.001 -0.001
2010-11-28 12:00:00       0   0  -0.001  0.003
2010-11-29 12:00:00       0   0   0.000  0.000
2010-11-30 12:00:00       0   0   0.000  0.000
2010-12-01 12:00:00       0   0   0.000  0.000
Run Code Online (Sandbox Code Playgroud)

我会更多地考虑一下这个问题.