【问题标题】:Down-sampling specific period on dataframe using Pandas使用 Pandas 对数据帧的特定周期进行下采样
【发布时间】:2017-08-16 23:53:07
【问题描述】:

我有一个从 1963 年开始到 2013 年结束的长时间系列。但是,从 1963 年到 2007 年,它有一个每小时的采样周期,而 2007 年之后的采样率变为 5 分钟。是否可以在 2007 年之后以整个时间序列每小时数据采样的方式重新采样数据?数据切片如下。

yr, m, d, h, m, s, sl
2007, 11, 30, 19, 0, 0, 2180
2007, 11, 30, 20, 0, 0, 2310
2007, 11, 30, 21, 0, 0, 2400
2007, 11, 30, 22, 0, 0, 2400
2007, 11, 30, 23, 0, 0, 2270
2008, 1, 1, 0, 0, 0, 2210
2008, 1, 1, 0, 5, 0, 2210
2008, 1, 1, 0, 10, 0, 2210
2008, 1, 1, 0, 15, 0, 2200
2008, 1, 1, 0, 20, 0, 2200
2008, 1, 1, 0, 25, 0, 2200
2008, 1, 1, 0, 30, 0, 2200
2008, 1, 1, 0, 35, 0, 2200
2008, 1, 1, 0, 40, 0, 2200
2008, 1, 1, 0, 45, 0, 2200
2008, 1, 1, 0, 50, 0, 2200
2008, 1, 1, 0, 55, 0, 2200
2008, 1, 1, 1, 0, 0, 2190
2008, 1, 1, 1, 5, 0, 2190  

谢谢!

【问题讨论】:

    标签: python pandas dataframe downsampling


    【解决方案1】:

    为您的数据框提供正确的列名

    df.columns = 'year month day hour minute second sl'.split()
    

    解决方案

    df.groupby(['year', 'month', 'day', 'hour'], as_index=False).first()
    
       year  month  day  hour  minute  second    sl
    0  2007     11   30    19       0       0  2180
    1  2007     11   30    20       0       0  2310
    2  2007     11   30    21       0       0  2400
    3  2007     11   30    22       0       0  2400
    4  2007     11   30    23       0       0  2270
    5  2008      1    1     0       0       0  2210
    6  2008      1    1     1       0       0  2190
    

    选项 2
    这是一个基于列重命名的选项。我们将使用pd.to_datetime 巧妙地获取我们的日期,然后使用resample。但是,您有时间间隔,必须处理空值并重新转换 dtype。

    df.set_index(
        pd.to_datetime(df.drop('sl', 1))
    ).resample('H').first().dropna().astype(df.dtypes)
    
                         year  month  day  hour  minute  second    sl
    2007-11-30 19:00:00  2007     11   30    19       0       0  2180
    2007-11-30 20:00:00  2007     11   30    20       0       0  2310
    2007-11-30 21:00:00  2007     11   30    21       0       0  2400
    2007-11-30 22:00:00  2007     11   30    22       0       0  2400
    2007-11-30 23:00:00  2007     11   30    23       0       0  2270
    2008-01-01 00:00:00  2008      1    1     0       0       0  2210
    2008-01-01 01:00:00  2008      1    1     1       0       0  2190
    

    【讨论】:

      【解决方案2】:

      为方便起见重命名分钟列:

      df.columns = ['yr', 'm', 'd', 'h', 'M', 's', 'sl']
      

      创建一个日期时间列:

      from datetime import datetime as dt
      df['dt'] = df.apply(axis=1, func=lambda x: dt(x.yr, x.m, x.d, x.h, x.M, x.s))
      

      重采样:

      对于熊猫

      df = df.set_index('dt').resample('60T').reset_index('dt')
      

      对于熊猫 >= 0.19:

      df = df.resample('60T', on='dt')
      

      【讨论】:

      • 如果你运行这个,你会发现你仍然需要处理来自空值的float和dtypes的空值。
      【解决方案3】:

      您最好先在数据框中附加一个日期时间列:
      df['datetime'] = pd.to_datetime(df[['yr', 'mnth', 'd', 'h', 'm', 's']])

      但在此之前,您应该重命名月份列:
      df.rename(columns={ df.columns[1]: "mnth" })

      然后将日期时间列设置为数据框索引:
      data.set_index('datetime', inplace=True)

      现在您可以通过首选采样率在您的数据帧上应用重采样方法:
      df.resample('60T', on='datatime').mean()

      这里我用mean来聚合。您可以根据需要使用其他方法。 请参阅Pandas document 作为参考。

      【讨论】:

      • 如果你运行这个,你会发现你仍然需要处理来自空值的float和dtypes的空值。
      猜你喜欢
      • 2020-11-12
      • 1970-01-01
      • 2012-10-02
      • 1970-01-01
      • 2019-12-28
      • 2013-09-20
      • 2017-05-22
      • 2016-01-10
      • 2018-02-01
      相关资源
      最近更新 更多