【问题标题】:How to resample a Pandas dataframe of mixed type?如何重新采样混合类型的 Pandas 数据框?
【发布时间】:2016-04-12 07:20:36
【问题描述】:

我使用以下 Python 代码生成混合类型(浮点数和字符串)Pandas DataFrame df3:

df1 = pd.DataFrame(np.random.randn(dates.shape[0],2),index=dates,columns=list('AB'))
df1['C'] = 'A'
df1['D'] = 'Pickles'
df2 = pd.DataFrame(np.random.randn(dates.shape[0], 2),index=dates,columns=list('AB'))
df2['C'] = 'B'
df2['D'] = 'Ham'
df3 = pd.concat([df1, df2], axis=0)

当我将 df3 重新采样到更高的频率时,我没有将帧重新采样到更高的速率,但如何被忽略,我只是得到了缺失值:

df4 = df3.groupby(['C']).resample('M',  how={'A': 'mean', 'B': 'mean',  'D': 'ffill'})
df4.head()

结果:

                      B          A        D
C                                          
A 2014-03-31 -0.4640906 -0.2435414  Pickles
  2014-04-30        NaN        NaN      NaN
  2014-05-31        NaN        NaN      NaN
  2014-06-30 -0.5626360  0.6679614  Pickles
  2014-07-31        NaN        NaN      NaN

当我将 df3 重新采样到较低频率时,我根本没有得到任何重新采样:

df5 = df3.groupby(['C']).resample('A',  how={'A': np.mean, 'B': np.mean,  'D': 'ffill'})
df5.head()

结果:

                      B          A        D
C                                          
A 2014-03-31        NaN        NaN  Pickles
  2014-06-30        NaN        NaN  Pickles
  2014-09-30        NaN        NaN  Pickles
  2014-12-31 -0.7429617 -0.1065645  Pickles
  2015-03-31        NaN        NaN  Pickles

我很确定这与混合类型有关,因为如果我只用数字列重做年度下采样,一切都会按预期工作:

df5b = df3[['A', 'B', 'C']].groupby(['C']).resample('A',  how={'A': np.mean, 'B': np.mean})
df5b.head()

结果:

                     B          A
  C                                 
  A 2014-12-31 -0.7429617 -0.1065645
    2015-12-31 -0.6245030 -0.3101057
  B 2014-12-31  0.4213621 -0.0708263
    2015-12-31 -0.0607028  0.0110456

但即使我切换到数字类型,重采样到更高频率仍然无法按预期工作:

df4b = df3[['A', 'B', 'C']].groupby(['C']).resample('M',  how={'A': 'mean', 'B': 'mean'})
df4b.head()

结果:

                      B          A
C                                 
A 2014-03-31 -0.4640906 -0.2435414
  2014-04-30        NaN        NaN
  2014-05-31        NaN        NaN
  2014-06-30 -0.5626360  0.6679614
  2014-07-31        NaN        NaN

这给我留下了两个问题:

  1. 对混合类型的数据帧重新采样的正确方法是什么?
  2. 从较低频率重新采样到较高频率时,进行重新采样以便插入新值的正确方法是什么?

即使您无法为这两个部分提供完整的答案,我们也感谢您提供部分解决方案或任何一个问题的答案。

【问题讨论】:

    标签: python numpy pandas time-series


    【解决方案1】:

    当从较低频率重新采样到较高频率时,我意识到我在指定 fill_method 时指定了 how。当我这样做时,事情似乎奏效了。

    df4c = df3.groupby(['C']).resample('M',  fill_method='ffill')
    df4c.head()
                         A          B        D
    C                                          
    A 2014-03-31 -0.2435414 -0.4640906  Pickles
      2014-04-30 -0.2435414 -0.4640906  Pickles
      2014-05-31 -0.2435414 -0.4640906  Pickles
      2014-06-30  0.6679614 -0.5626360  Pickles
      2014-07-31  0.6679614 -0.5626360  Pickles
    

    您获得的插值选择要有限得多,但它确实可以处理混合类型。

    当不使用 how 选项(我相信它的默认值)重新采样到较低频率时,下采样确实有效:

       df5c =df3.groupby(['C']).resample('A')
       df5c.head()
                      A          B
    C                                 
    A 2014-12-31 -0.1065645 -0.7429617
      2015-12-31 -0.3101057 -0.6245030
    B 2014-12-31 -0.0708263  0.4213621
      2015-12-31  0.0110456 -0.0607028
    

    因此,问题似乎在于传递 how 选项的字典或其中一个选项选项,大概是 ffill,但我不确定。

    【讨论】:

      【解决方案2】:

      使用resample 和agg

      自从pandas-1.0.0,how and fill_method keywords no longer exist。 此外,resample 方法现在是returns a Resampler object。

      解决方案是使用与每列关联的函数或函数名称来定义聚合规则。

      df.resample(period).agg(aggregation_rule)
      

      更多关于聚合规则的例子in the documentation。

      工作示例

      准备测试数据:

      import numpy as np
      import pandas as pd
      
      dates = pd.date_range("2021-02-09", "2021-04-09", freq="1D")
      df1 = pd.DataFrame(np.random.randn(dates.shape[0],2), index=dates, columns=list('AB'))
      df1['C'] = 'A'
      df1['D'] = 'Pickles'
      df2 = pd.DataFrame(np.random.randn(dates.shape[0], 2), index=dates, columns=list('AB'))
      df2['C'] = 'B'
      df2['D'] = 'Ham'
      df3 = pd.concat([df1, df2], axis=0)
      print(df3)
      

      输出:

                         A         B  C        D
      2021-02-09  2.591285  2.455686  A  Pickles
      2021-02-10  0.753461 -0.072643  A  Pickles
      2021-02-11 -0.351667 -0.025511  A  Pickles
      2021-02-12 -0.896730  0.004512  A  Pickles
      2021-02-13 -0.493139 -0.770514  A  Pickles
      ...              ...       ... ..      ...
      2021-04-05  1.615935  1.152517  B      Ham
      2021-04-06 -0.067654 -0.858186  B      Ham
      2021-04-07  0.085587 -0.848542  B      Ham
      2021-04-08 -0.371983  0.088441  B      Ham
      2021-04-09  0.681501  0.235328  B      Ham
      
      [120 rows x 4 columns]
      

      每月重新采样:

      agg_rules = { "A": "mean", "B": "sum", "C": "first", "D": "last",}
      df4 = df3.resample("M").agg(agg_rules)
      print(df4)
      

      输出:

                         A         B  C    D
      2021-02-28  0.025987  3.886781  A  Ham
      2021-03-31  0.081423 -5.492928  A  Ham
      2021-04-30  0.239309 -3.344334  A  Ham
      

      【讨论】:

        猜你喜欢
        • 2019-04-15
        • 2020-02-06
        • 1970-01-01
        • 2017-09-19
        • 1970-01-01
        • 2014-10-04
        • 2013-01-13
        • 1970-01-01
        • 2019-06-14
        相关资源
        最近更新 更多