【问题标题】:Resampling with pandas.MultiIndex: Resampler.aggregate() & Resampler[column]使用 pandas.MultiIndex 重采样:Resampler.aggregate() & Resampler[column]
【发布时间】:2020-01-12 09:20:54
【问题描述】:

我正在尝试重新采样数据框。首先,我想在结果中保留几个聚合。其次,对于特定列,还有一个额外的聚合感兴趣。由于此聚合仅与单个列相关,因此可以将重采样器限制在此列,以免不必要地将聚合应用于其他列。

此方案适用于简单的一维列索引:

import numpy as np
import pandas as pd
df = pd.DataFrame(data=np.random.rand(50,4), index=pd.to_datetime(np.arange(0, 50), unit="s"), columns=["a", "b", "c", "d"])
r = df.resample("10s")
result = r.aggregate(["mean", "std"])
result[("d", "ffill")] = r["d"].ffill()
print(result)

但是,一旦我开始使用多索引列,问题就出现了。首先,我不能同时保留多个聚合:

df.columns = pd.MultiIndex.from_product([("a", "b"), ("alpha", "beta")])
r = df.resample("10s")    # can be omitted
result = r.aggregate(["mean", "std"])
---> AttributeError: 'Series' object has no attribute 'columns'

第二,重采样器不能再局限于相关列:

r[("b", "beta")].ffill()
--> KeyError: "Columns not found: 'b', 'beta'"

如何将我的关注点从简单指数转变为多指数?

【问题讨论】:

    标签: python pandas pandas-groupby multi-index


    【解决方案1】:

    这一定是aggregate 中的错误。复飞将是stack

    (df.stack().groupby(level=-1)
      .apply(lambda x:x.resample('10s', level=0).aggregate(["mean", "std"]))
      .unstack(level=0)
    )
    

    【讨论】:

      【解决方案2】:

      您可以在groupby 中使用pd.Grouper,而不是重新采样,例如:

      result = df.groupby(pd.Grouper(freq='10s',level=0)).aggregate(["mean", "std"])
      print (result)
                                 a                                       b  \
                              alpha                beta               alpha   
                               mean       std      mean       std      mean   
      1970-01-01 00:00:00  0.460569  0.312508  0.476511  0.260534  0.479577   
      1970-01-01 00:00:10  0.441498  0.315277  0.487855  0.306068  0.535842   
      1970-01-01 00:00:20  0.569884  0.248503  0.320552  0.288479  0.507755   
      1970-01-01 00:00:30  0.478037  0.262654  0.552214  0.251581  0.505132   
      1970-01-01 00:00:40  0.611227  0.328916  0.473773  0.241604  0.358298   
      
      
                                         beta            
                                std      mean       std  
      1970-01-01 00:00:00  0.357493  0.448487  0.294432  
      1970-01-01 00:00:10  0.259145  0.472250  0.320954  
      1970-01-01 00:00:20  0.369490  0.432944  0.150473  
      1970-01-01 00:00:30  0.298759  0.381614  0.248785  
      1970-01-01 00:00:40  0.203831  0.381412  0.374965  
      

      对于第二部分,我不确定你的意思,但是根据单列级别的情况下给出的结果,试试这个它给出了一个结果

      result[("b", "beta",'ffill')] = df.groupby(pd.Grouper(freq='10s',level=0))[[("b", "beta")]].first()
      

      【讨论】:

      • 首先,使用groupbypd.Grouper 可以解决aggregate 的问题。正如 Quang Hoang 所提到的,它不适用于resample 似乎确实是错误。其次,重要的是重新执行“计算密集型”分组。但是,在重用DataFrameGroupBy 对象的同时将多索引元组封装在一个列表中可以解决问题:r[[("b", "beta")]].first()。顺便说一句,first() 是更合适的操作。谢谢!
      • @Chickenmarkus 确实两次groupby 不是最好的,但我认为您会像使用r 一样创建它。你的第二句话让我觉得在 Multiindex 的情况下,使用r = df.resample("10s"),如果你使用r[df.columns].aggregate(["mean", "std"]),它实际上可以按预期工作:)
      猜你喜欢
      • 1970-01-01
      • 2022-01-04
      • 2013-06-09
      • 2022-01-21
      • 2017-06-07
      • 1970-01-01
      • 2019-09-03
      • 2018-12-27
      • 2014-01-20
      相关资源
      最近更新 更多