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

如何在Pandas中按类别(如Area列)添加连续日期行?

实现方案

注意:Pandas 1.4.0之后append()方法已被弃用,推荐用pd.concat()实现行追加,以下是具体步骤:

步骤1:数据预处理(转换日期格式)

先把Start和End列转成datetime类型,方便后续日期计算:

import pandas as pd

# 原始数据
data = {
    'Start': ['2/1/2022', '3/1/2022', '2/1/2022', '3/1/2022'],
    'End': ['3/1/2022', '4/1/2022', '3/1/2022', '4/1/2022'],
    'Area': ['NY', 'NY', 'CA', 'CA'],
    'ID': [222, 111, 333, 100],
    'Stat': ['Y', 'Y', 'Y', 'Y']
}
df = pd.DataFrame(data)

# 转换日期列
df['Start'] = pd.to_datetime(df['Start'])
df['End'] = pd.to_datetime(df['End'])

步骤2:生成每个Area的新增行

按Area分组,为每个组生成一行新数据:

new_rows = []
for area, group in df.groupby('Area'):
    # 取组内最后一行的End日期作为新行的Start
    last_end = group['End'].iloc[-1]
    # 计算新行的End日期(加1个月)
    new_end = last_end + pd.DateOffset(months=1)
    # 构造新行,ID和Stat留空
    new_row = pd.DataFrame({
        'Start': [last_end],
        'End': [new_end],
        'Area': [area],
        'ID': [None],
        'Stat': [None]
    })
    new_rows.append(new_row)

# 合并所有新行
new_df = pd.concat(new_rows, ignore_index=True)

步骤3:合并原数据与新行并排序

把原数据和新行合并,然后按Area和Start排序,保持原分组顺序:

# 合并数据
result = pd.concat([df, new_df], ignore_index=True)
# 排序:先按Area分组,再按Start日期排序
result = result.sort_values(by=['Area', 'Start'], ignore_index=True)

# 转换回原始日期格式(可选,根据需求调整)
result['Start'] = result['Start'].dt.strftime('%m/%d/%Y')
result['End'] = result['End'].dt.strftime('%m/%d/%Y')
# 把NaN替换为空白(可选)
result = result.fillna('')

print(result.to_string(index=False))

运行后得到期望结果:

Start       End Area  ID Stat
02/01/2022 03/01/2022  NY 222    Y
03/01/2022 04/01/2022  NY 111    Y
04/01/2022 05/01/2022  NY     
02/01/2022 03/01/2022  CA 333    Y
03/01/2022 04/01/2022  CA 100    Y
04/01/2022 05/01/2022  CA     

补充说明

  • 若日期不是每月1号,pd.DateOffset(months=1)也能正确计算下一个月的对应日期;
  • concat()比弃用的append()效率更高,尤其是处理大数据量时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:55:25