重新采样MultiIndexed Pandas DataFrame并将不同的函数应用于列

时间:2017-05-03 08:18:18

标签: python python-3.x pandas numpy dictionary

如果您没有MultiIndexed列,则可以执行df.resample(freq).agg(some_dict)其中some_dict的格式为{column_name: function},以便为每列应用不同的函数(请参阅下面的演示或参见{ {3}}或this question)。

当我有MultiIndexed列时,我想做同样的事情,但是Pandas正在我的列和字典之间做产品。

这里有一些假数据:

In [1]:
import pandas as pd
import numpy as np

cols = pd.MultiIndex.from_tuples([('A', 'one'), ('A', 'two'),
                                 ('B', 'one'), ('B', 'two')])
ind = pd.DatetimeIndex(start='2017-01-01', freq='15Min', periods=20)
df = pd.DataFrame(np.random.randn(20,4), index=ind, columns=cols)
print(df.head())

Out[1]:

                            A                   B          
                          one       two       one       two
2017-01-01 00:00:00 -0.627329  0.756533  2.149236 -1.204808
2017-01-01 00:15:00  1.493381  1.320806 -1.692557  1.225271
2017-01-01 00:30:00 -0.572762  1.365679 -1.993464  1.118474
2017-01-01 00:45:00 -1.785283 -1.625370 -0.437199  0.776267
2017-01-01 01:00:00 -0.220307  1.308388  2.981333 -0.569586

现在,让我们创建一个聚合字典,将列映射到特定的函数:

In [2]:
agg_dict = { col:(np.sum if col[1] == 'one' else np.mean) for col in df.columns }

agg_dict

Out[2]:
{('A', 'one'): <function numpy.core.fromnumeric.sum>,
 ('A', 'two'): <function numpy.core.fromnumeric.mean>,
 ('B', 'one'): <function numpy.core.fromnumeric.sum>,
 ('B', 'two'): <function numpy.core.fromnumeric.mean>}

这里它不起作用,它实际上是在我的实际列和agg_dict之间的产品。我期待(5,4)的形状,但我得到(5,16)(dict中的4个条目,df中的4个列):

In [3]: df.resample('H').agg(agg_dict).shape
Out[3]: (5,16)

In [4]: print(df.resample('H').agg(agg_dict).columns.tolist())
Out[4]: [('A', 'one', 'A', 'one'), ('A', 'one', 'A', 'two'), ('A', 'one', 'B', 'one'), ('A', 'one', 'B', 'two'), ('A', 'two', 'A', 'one'), ('A', 'two', 'A', 'two'), ('A', 'two', 'B', 'one'), ('A', 'two', 'B', 'two'), ('B', 'one', 'A', 'one'), ('B', 'one', 'A', 'two'), ('B', 'one', 'B', 'one'), ('B', 'one', 'B', 'two'), ('B', 'two', 'A', 'one'), ('B', 'two', 'A', 'two'), ('B', 'two', 'B', 'one'), ('B', 'two', 'B', 'two')]

如何获得与非MultiIndexed案例相似的行为,最终会在此处使用(5,4)数据框?

我可以验证它是否可以使用非MultiIndexed DataFrame。

In [5]:
df2 = df.copy()
# Flatten columns
df2.columns = ['_'.join(x) for x in df.columns]
# Create similar agg_dict
agg_dict2 = { col:(np.sum if 'one' in col else np.mean) for col in df2.columns }
print(df2.resample('H').agg(agg_dict2))

Out[5]:

                        A_one     A_two     B_one     B_two
2017-01-01 00:00:00 -1.491994  0.454412 -1.973983  0.478801
2017-01-01 01:00:00 -0.931024  0.465611  4.837972 -0.118674
2017-01-01 02:00:00  2.015399  0.203814  1.539722 -0.296053
2017-01-01 03:00:00 -0.569376 -0.382343 -2.244470 -0.038828
2017-01-01 04:00:00 -0.747308 -0.212246  2.025314  0.713344

1 个答案:

答案 0 :(得分:0)

我刚想出了一个使用applylambda

的作品
In [1]:
df.resample('H').apply(lambda x: agg_dict[x.name](x))

Out[1]:
                            A                   B          
                          one       two       one       two
2017-01-01 00:00:00 -2.211489  0.538068  1.379451 -0.619921
2017-01-01 01:00:00  1.524752 -0.195767  1.157592  0.137513
2017-01-01 02:00:00 -1.225071  0.020599 -1.372751 -0.245233
2017-01-01 03:00:00  2.922656  0.032864  3.118994  0.315109
2017-01-01 04:00:00 -1.438694  1.025585  1.915400 -0.536389

x.name返回例如('A', 'one'),因此我使用它来选择dict中的函数,并将x传递给它。