使用 Pandas 对数据帧的特定周期进行下采样

Down-sampling specific period on dataframe using Pandas

我有一个很长的时间系列,从 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  

谢谢!

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

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。但是,您有时间间隔,必须解决空值并重新转换数据类型。

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

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

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))

重新采样:

对于 pandas < 0.19:

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

对于 pandas >= 0.19:

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

您最好先将日期时间列附加到您的数据框:
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 作为参考。