You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从多年度日Dataframe生成周Dataframe的跨年分组问题

问题:跨年周数据拆分异常(2018年12月31日单独成周)

基于2016-2022年的日度Dataframe生成周度数据时,现有代码整体运行正常,但2018年12月31日被单独划分为一周,实际该日期应归入2019年1月4日结束的周,求修复方案。

日度Dataframe:

DateOpenHighLowClose
24-Dec-20182692526982.626737.126810
26-Dec-2018267002707026439.627067.8
27-Dec-201827198272602686026877.6
28-Dec-2018271552735027051.0527290
31-Dec-20182740027429.527242.127318
01-Jan-201927300.2275322713527526
02-Jan-201927410.32752327175.127275.3
03-Jan-20192726027319.427062.327076
04-Jan-201927169274312705827376
07-Jan-20192755527586.752737527382.2
08-Jan-201927388.427632.652729227610.2
09-Jan-201927752.227784.427451.427752
10-Jan-201927720.32774027587.127630.05
11-Jan-20192767527689.927502.5527533
14-Jan-2019274652748027300.9527347.6
15-Jan-201927410.62753927392.127520

现有代码输出:

DateweekdayOpenHighLowClose
21-Dec-2018Friday26988.82742526888.626971.8
28-Dec-2018Friday269252735026439.627290
31-Dec-2018Monday2740027429.527242.127318
04-Jan-2019Friday27300.2275322705827376
11-Jan-2019Friday2755527784.42729227533
18-Jan-2019Friday274652767627300.9527560
25-Jan-2019Friday27560.0527674.952706727158.95

当前使用的代码:

temp_df = daily_df.copy()
temp_df['Date'] = pd.to_datetime(temp_df['Date'], format='%d-%b-%Y')
weekly_data = temp_df.assign(wk=temp_df['Date'].dt.isocalendar().week, ye=temp_df['Date'].dt.year, iso_ye=temp_df['Date'].dt.isocalendar().year).groupby(['wk', 'ye', 'iso_ye']).aggregate({'Date': ['max'], 'Open': ['first'],'High': ['max'], 'Low': ['min'],
            'Close': ['last']}).reset_index()

# check if maximum date in week is in previous year
weekly_data.loc[weekly_data['Date', 'max'].dt.year != weekly_data['iso_ye'], 'wk'] = 1

weekly_data.columns = weekly_data.columns.droplevel(1)
weekly_data = weekly_data.sort_values(by=['Date']).drop(columns=['ye', 'iso_ye']).reset_index(drop=True)
weekly_data['weekday'] = weekly_data['Date'].dt.day_name()
weekly_data['Date'] = pd.to_datetime(weekly_data['Date'], format='%Y%m%d')
weekly_data['Date'] = weekly_data['Date'].dt.strftime('%d-%b-%Y')
weekly_data.drop(['wk'], axis=1)
weekly_data = weekly_data.reindex(columns=['Date', 'weekday', 'Open', 'High', 'Low', 'Close'])
weekly_data

解决方案

问题根源在于原代码同时用公历年份(ye)和ISO周+ISO年份分组,导致2018年12月31日(ISO周属于2019年第1周,但公历年份是2018)被单独拆分。正确做法是直接用ISO年份和ISO周作为唯一分组键,完全对齐ISO周的规则。

修改后的代码:

temp_df = daily_df.copy()
temp_df['Date'] = pd.to_datetime(temp_df['Date'], format='%d-%b-%Y')

# 直接使用ISO年份和ISO周分组,避免公历年份干扰
weekly_data = temp_df.assign(
    iso_year=temp_df['Date'].dt.isocalendar().year,
    iso_week=temp_df['Date'].dt.isocalendar().week
).groupby(['iso_year', 'iso_week']).aggregate({
    'Date': ['max'],
    'Open': ['first'],
    'High': ['max'],
    'Low': ['min'],
    'Close': ['last']
}).reset_index()

# 处理列名和格式
weekly_data.columns = weekly_data.columns.droplevel(1)
weekly_data = weekly_data.sort_values(by=['Date']).drop(columns=['iso_year', 'iso_week']).reset_index(drop=True)
weekly_data['weekday'] = weekly_data['Date'].dt.day_name()
weekly_data['Date'] = weekly_data['Date'].dt.strftime('%d-%b-%Y')
weekly_data = weekly_data.reindex(columns=['Date', 'weekday', 'Open', 'High', 'Low', 'Close'])
weekly_data

修改后预期输出

DateweekdayOpenHighLowClose
21-Dec-2018Friday26988.82742526888.626971.8
28-Dec-2018Friday269252735026439.627290
04-Jan-2019Friday27400275322705827376
11-Jan-2019Friday2755527784.42729227533
18-Jan-2019Friday274652767627300.9527560
25-Jan-2019Friday27560.0527674.952706727158.95

可以看到,2018年12月31日已经和2019年1月1-4日合并为同一周,周结束日期显示为2019年1月4日,Open取该周第一个交易日(12月31日)的数值,其他字段也按周维度正确聚合。

内容的提问来源于stack exchange,提问作者vineet singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 20:06:58