使用 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 作为参考。
我有一个很长的时间系列,从 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 作为参考。