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

基于日期复制DataFrame行并拆分Expences字段的实现问题

解决方案

数据预处理

首先要把日期相关字段转为标准日期格式,方便后续年月比较与计算:

import pandas as pd
import numpy as np

# 转换日期格式(假设数据已加载为df)
df['Signed_Date'] = pd.to_datetime(df['Signed_Date'], format='%B %Y')
df['start_Date'] = pd.to_datetime(df['start_Date'])
df['end_Date'] = pd.to_datetime(df['end_Date'])

核心处理逻辑

我们分两部分生成最终数据:一是按start_Date到end_Date的月份拆分的常规行,二是当Signed_Date与start_Date年月不一致时的额外费用行。

1. 生成月份拆分的常规行

为每个Event生成覆盖时间段内的所有月份行,并均分ticket、Revenue、expect字段:

def generate_monthly_rows(row):
    # 生成start到end之间的所有月份第一天(包含首尾月)
    date_range = pd.date_range(
        start=row['start_Date'].replace(day=1),
        end=row['end_Date'].replace(day=1),
        freq='MS'
    )
    month_count = len(date_range)
    
    # 复制行并均分数值字段
    split_row = row.copy()
    split_row['ticket'] = row['ticket'] / month_count if pd.notna(row['ticket']) else np.nan
    split_row['Revenue'] = row['Revenue'] / month_count if pd.notna(row['Revenue']) else np.nan
    split_row['expect'] = row['expect'] / month_count if pd.notna(row['expect']) else np.nan
    split_row['Expences'] = 0  # 原费用将移到额外行
    
    # 生成每行的Event_Date:首月用start_Date,其余用当月第一天
    event_dates = [row['start_Date']] + list(date_range[1:])
    
    # 组装多行数据
    rows = []
    for ed in event_dates:
        temp = split_row.copy()
        temp['Event_Date'] = ed
        rows.append(temp)
    return pd.DataFrame(rows)

# 应用到所有行并合并结果
monthly_df = pd.concat([generate_monthly_rows(row) for _, row in df.iterrows()], ignore_index=True)

2. 生成额外费用行(年月不一致时)

筛选出Signed_Date与start_Date年月不同的记录,生成单独的费用行:

# 筛选需要生成额外行的记录
diff_month_mask = (df['Signed_Date'].dt.to_period('M') != df['start_Date'].dt.to_period('M'))
extra_rows = df[diff_month_mask].copy()

# 设置数值字段为0,保留原Expences值
extra_rows['ticket'] = 0
extra_rows['Revenue'] = 0
extra_rows['expect'] = 0
# 生成Event_Date为Signed_Date当月第一天
extra_rows['Event_Date'] = extra_rows['Signed_Date'].replace(day=1)

3. 合并数据并整理

把常规拆分行和额外行合并,按Event_ID与Event_Date排序:

final_df = pd.concat([monthly_df, extra_rows], ignore_index=True)
# 排序并调整列顺序
final_df = final_df.sort_values(by=['Event_ID', 'Event_Date'], ignore_index=True)
final_df = final_df[['Event_ID', 'ticket', 'Revenue', 'Expences', 'expect', 'Signed_Date', 'start_Date', 'end_Date', 'Event_Date']]
# 格式化数值为两位小数(匹配示例格式)
final_df[['ticket', 'Revenue', 'Expences', 'expect']] = final_df[['ticket', 'Revenue', 'Expences', 'expect']].round(2)

结果示例

运行后,G-00002的输出与需求示例一致:

Event_IDticketRevenueExpencesexpectSigned_Datestart_Dateend_DateEvent_Date
G-000023.0028.000.0050.002021-05-012021-06-132021-07-132021-06-13
G-000023.0028.000.0050.002021-05-012021-06-132021-07-132021-07-01
G-000020.000.0018.000.002021-05-012021-06-132021-07-132021-05-01

原代码问题说明

你之前的代码仅复制了指定索引的单行,未批量处理所有符合条件的记录,也未实现字段均分、月份拆分等核心逻辑,上述方案完整覆盖了所有需求点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:45:42