Skip to main content
 首页 » 编程设计

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

2025年05月04日14softidea

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