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

基于Date_2列日期条件创建新DataFrame的技术求助

需求背景与现有数据

现有DataFrame结构如下:

Date_1         Type_1     Qty_1     Date_2         Type_2      Qty_2
29-12-2023       A          1       01-01-2024       B           2
29-12-2023       A          3       01-01-2024       B           4
30-12-2023       A          2       01-01-2024       B           3
30-12-2023       A          5       02-01-2024       B           5
31-12-2023       A          10      02-01-2024       B           6
31-12-2023       A          2       03-01-2024       B           1
01-01-2024       A          1       04-01-2023       B           2
核心需求

需针对Date_2列的唯一日期值执行以下逻辑,创建新DataFrame:

  • 若该日期为周一:提取Date_1列中该日期前三天的所有Type_1、Qty_1数据,追加该日期对应的所有Type_2、Qty_2数据;
  • 若为其他日期:提取Date_1列中该日期前一天的所有Type_1、Qty_1数据,追加该日期对应的所有Type_2、Qty_2数据。
现状与问题

已编写部分Python代码但陷入瓶颈,代码如下:

from datetime import datetime, timedelta 
# Function to find previous three dates for a given date
def get_previous_three_dates(date):
    return [date - timedelta(days=i) for i in range(1, 4)]

#Function to get Type and Value for previous three dates if the given date is Monday
def get_type_value_for_previous_dates(df, column_name):
    result = []
    for index, row in df.iterrows():
        if row[column_name].weekday() == 0:  # Check if the date is Monday (Monday corresponds to 0)
            previous_dates = get_previous_three_dates(row[column_name])
            for prev_date in previous_dates:
                # Check if the previous date exists in the DataFrame
                if prev_date in df['Date_1'].values:
                    entry = df[df['Date_1'] == prev_date][['Type_1', 'Sales_1']].iloc[0].to_dict()
                    result.append({ 'Date': prev_date, 'Type': entry['Type_1'], 'Qty': entry['Sales_1']})
    return result
解决思路与完整实现

关键优化点

  1. 优先统一日期格式:将Date_1和Date_2转换为datetime类型,避免字符串匹配错误;
  2. 避免重复处理:提取Date_2的唯一值进行遍历,减少冗余计算;
  3. 用Pandas向量操作替代行遍历:提升效率同时简化逻辑。

完整代码

import pandas as pd
from datetime import datetime, timedelta

# 初始化示例数据(实际场景可替换为读取数据源)
data = {
    'Date_1': ['29-12-2023', '29-12-2023', '30-12-2023', '30-12-2023', '31-12-2023', '31-12-2023', '01-01-2024'],
    'Type_1': ['A', 'A', 'A', 'A', 'A', 'A', 'A'],
    'Qty_1': [1, 3, 2, 5, 10, 2, 1],
    'Date_2': ['01-01-2024', '01-01-2024', '01-01-2024', '02-01-2024', '02-01-2024', '03-01-2024', '04-01-2024'],
    'Type_2': ['B', 'B', 'B', 'B', 'B', 'B', 'B'],
    'Qty_2': [2, 4, 3, 5, 6, 1, 2]
}
df = pd.DataFrame(data)

# 转换日期格式为datetime类型
df['Date_1'] = pd.to_datetime(df['Date_1'], format='%d-%m-%Y')
df['Date_2'] = pd.to_datetime(df['Date_2'], format='%d-%m-%Y')

# 存储最终结果的空DataFrame
final_df = pd.DataFrame()

# 遍历Date_2的每个唯一日期
for target_date in df['Date_2'].unique():
    # 提取当前目标日期对应的Type_2、Qty_2数据,统一列名
    type2_part = df[df['Date_2'] == target_date][['Type_2', 'Qty_2']].rename(columns={'Type_2': 'Type', 'Qty_2': 'Qty'})
    type2_part['Data_Source'] = 'Type_2'  # 可选:标记数据来源,方便验证
    
    # 判断目标日期是否为周一
    if target_date.weekday() == 0:
        # 计算前三天的日期范围(含起始和结束)
        start_prev = target_date - timedelta(days=3)
        end_prev = target_date - timedelta(days=1)
        # 提取Date_1在该范围内的Type_1、Qty_1数据
        type1_part = df[(df['Date_1'] >= start_prev) & (df['Date_1'] <= end_prev)][['Type_1', 'Qty_1']].rename(columns={'Type_1': 'Type', 'Qty_1': 'Qty'})
    else:
        # 计算前一天的日期
        prev_day = target_date - timedelta(days=1)
        # 提取Date_1等于该日期的Type_1、Qty_1数据
        type1_part = df[df['Date_1'] == prev_day][['Type_1', 'Qty_1']].rename(columns={'Type_1': 'Type', 'Qty_1': 'Qty'})
    
    type1_part['Data_Source'] = 'Type_1'  # 可选:标记数据来源
    # 合并当前目标日期的两部分数据
    current_result = pd.concat([type1_part, type2_part], ignore_index=True)
    # 添加目标日期列,明确每条数据对应的Date_2日期
    current_result['Target_Date'] = target_date
    # 追加到最终结果
    final_df = pd.concat([final_df, current_result], ignore_index=True)

# 打印最终结果
print(final_df)

代码说明

  • 日期转换确保了日期比较的准确性,避免因字符串格式不一致导致的匹配失败;
  • 用unique()处理Date_2,避免对同一日期重复执行逻辑;
  • 统一列名后用concat()合并数据,保证结果结构一致;
  • 可选的Data_Source列用于区分数据来自Type_1还是Type_2,便于后续验证和分析。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:30:57