如何让Pandas按每年首日开始对DataFrame执行3天周期重采样
如何让Pandas按每年首日开始对DataFrame执行3天周期重采样
我完全理解你的困扰——你希望每一年都从1月1日开始,按3天为一个周期对OHLC数据做重采样,但之前的方法要么是从数据起始日期延续周期,要么用origin只能管第一年,后面的年份没法自动重置起始点。
问题出在resample的origin参数是全局生效的,一旦设置成某一年的元旦,后续年份的周期会一直沿用这个起始点的计算逻辑,导致2021年的第一个周期不是从元旦开始。要解决这个,我们可以按年份分组,对每一年的数据单独处理重采样,这样就能给每个年份设置专属的元旦起始点了。
具体解决方案
我们可以把数据按年份拆分成多个子数据集,对每个子数据集单独用当年的1月1日作为origin执行重采样,最后再合并所有结果:
import pandas as pd import numpy as np # 复用你生成数据的代码(确保数据一致) np.random.seed(42) dates = pd.date_range(start='2020-06-25', periods=1679, freq='D') open_prices = np.random.uniform(low=100, high=200, size=len(dates)) high_prices = open_prices + np.random.uniform(low=0, high=10, size=len(dates)) low_prices = open_prices - np.random.uniform(low=0, high=10, size=len(dates)) close_prices = np.random.uniform(low=low_prices, high=high_prices) ohlc_data = pd.DataFrame({ 'Open': open_prices, 'High': high_prices, 'Low': low_prices, 'Close': close_prices }, index=dates) # 定义聚合规则 agg = {'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last'} # 按年份分组处理重采样 resampled_list = [] for year, yearly_data in ohlc_data.groupby(ohlc_data.index.year): # 为当前年份设置1月1日作为重采样起始点 year_origin = f"{year}-01-01" yearly_resampled = yearly_data.resample('3D', origin=year_origin).agg(agg) resampled_list.append(yearly_resampled) # 合并所有年份的结果 final_resampled = pd.concat(resampled_list)
验证效果
现在看2021年的结果,就会从1月1日开始生成3天周期了:
print(final_resampled.loc['2021-01-01': '2021-01-06'])
输出会类似:
Open High Low Close Date 2021-01-01 190.041806 192.176919 128.095988 134.056420 # 包含2021-01-01至01-03的聚合数据 2021-01-04 134.920957 195.614503 129.865870 189.599085 # 包含2021-01-04至01-06的聚合数据
而2020年因为数据从6月25日开始,重采样会自动从第一个有数据的周期(2020-06-25,属于2020年元旦开始的第n个3天周期)开始,和你之前的需求一致,不会有问题。
为什么这个方法可行?
通过按年份分组,我们把每个年份的数据独立出来处理,给每个年份单独设置origin为当年的元旦,这样每个年份的3天周期都是从自己的首日开始计算,完全不受前一年的周期影响,完美解决了全局origin的局限性。
备注:内容来源于stack exchange,提问作者x_crypto
相关产品推荐
相关产品推荐

