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

如何根据两个日期间的周数重复Pandas DataFrame行?

问题:按周数重复DataFrame行并生成连续周数

原始数据

import pandas as pd

df = pd.DataFrame(
    {
        'ID': ['ID001', 'ID002', 'ID003'],
        'DATE': ['24/12/2023', '01/02/2024', '12/02/2024'],
    }
)

df['DATE'] = pd.to_datetime(df['DATE'], dayfirst=True)
print(df)

输出:

ID       DATE
0  ID001 2023-12-24
1  ID002 2024-02-01
2  ID003 2024-02-12

需求

为每个ID重复N次行,N是DATE列与当前日期之间的周数;每行需对应从DATE所在周开始,到当前周的连续周数,同时匹配周对应的年份。

错误尝试代码及输出

number_of_weeks = (pd.Timestamp('now') - df['DATE']).dt.days // 7

final = df.copy()
final['YEAR'] = final['DATE'].dt.isocalendar().year
final['WEEK'] = final['DATE'].dt.isocalendar().week
final['WEEKS'] = (pd.Timestamp('now') - df['DATE']).dt.days // 7

for index, row in final.iterrows():
    for i in range(1, row['WEEKS'] + 1):
        final.loc[i, 'WEEK'] = i

final = final.ffill().drop(columns='WEEKS')

print(final)

输出:

ID       DATE  YEAR  WEEK
0  ID001 2023-12-24  2023    51
1  ID002 2024-02-01  2024     1
2  ID003 2024-02-12  2024     2
3  ID003 2024-02-12  2024     3
4  ID003 2024-02-12  2024     4
5  ID003 2024-02-12  2024     5
6  ID003 2024-02-12  2024     6
7  ID003 2024-02-12  2024     7

正确解决方案

原问题出在没有为每个ID新增行,而是直接覆盖现有索引的WEEK值。正确做法是为每个ID生成包含连续周数的序列,再合并到原数据中:

import pandas as pd

# 原始数据处理
df = pd.DataFrame(
    {
        'ID': ['ID001', 'ID002', 'ID003'],
        'DATE': ['24/12/2023', '01/02/2024', '12/02/2024'],
    }
)
df['DATE'] = pd.to_datetime(df['DATE'], dayfirst=True)

# 获取当前日期的ISO周信息
current_date = pd.Timestamp('now')
current_year, current_week, _ = current_date.isocalendar()

# 为每行生成周数序列
def generate_week_series(row):
    start_year, start_week, _ = row['DATE'].isocalendar()
    weeks_list = []
    
    # 分情况处理跨年份的周数生成
    if start_year == current_year:
        weeks = list(range(start_week, current_week + 1))
        weeks_list.extend([(start_year, w) for w in weeks])
    else:
        # 处理起始年剩余的周
        weeks_remaining = list(range(start_week, 53))
        weeks_list.extend([(start_year, w) for w in weeks_remaining if pd.Timestamp.fromisocalendar(start_year, w, 1) <= current_date])
        # 处理中间年份的所有周(如果有的话)
        for year in range(start_year + 1, current_year):
            weeks_list.extend([(year, w) for w in range(1, 53)])
        # 处理当前年的周
        weeks_current = list(range(1, current_week + 1))
        weeks_list.extend([(current_year, w) for w in weeks_current])
    
    # 生成对应行的重复数据
    rows = []
    for year, week in weeks_list:
        rows.append({
            'ID': row['ID'],
            'DATE': row['DATE'],
            'YEAR': year,
            'WEEK': week
        })
    return pd.DataFrame(rows)

# 应用函数并合并结果
final_df = pd.concat([generate_week_series(row) for _, row in df.iterrows()], ignore_index=True)

print(final_df)

说明

  1. 先获取当前日期的ISO周年份和周数,确保序列截止到当前周
  2. 针对每个ID的起始日期,分情况处理跨年份的周数:
    • 同一年份直接生成从起始周到当前周的连续序列
    • 跨年份则分别处理起始年剩余周、中间年份全周、当前年的周
  3. 为每个周生成对应的行,保留原始ID和DATE,匹配对应周的YEAR和WEEK

预期输出示例(以当前周为2024年第7周为例)

ID       DATE  YEAR  WEEK
0   ID001 2023-12-24  2023    51
1   ID001 2023-12-24  2023    52
2   ID001 2023-12-24  2024     1
3   ID001 2023-12-24  2024     2
4   ID001 2023-12-24  2024     3
5   ID001 2023-12-24  2024     4
6   ID001 2023-12-24  2024     5
7   ID001 2023-12-24  2024     6
8   ID001 2023-12-24  2024     7
9   ID002 2024-02-01  2024     5
10  ID002 2024-02-01  2024     6
11  ID002 2024-02-01  2024     7
12  ID003 2024-02-12  2024     7

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 05:40:37