遍历日期范围并匹配数据生成新DataFrame的实现咨询
遍历日期范围并匹配数据生成新DataFrame的实现咨询
我来帮你梳理清楚实现思路和具体代码,你要做的本质是把每条用户记录和日期范围里的每一天做组合匹配,筛选出符合条件的条目,最终生成带CurrentDate的目标DataFrame。
需求明确
你需要实现的核心逻辑对应以下规则:
- 生成2024-06-01至2024-12-10的所有日期
- 对原始DataFrame的每一行,检查每个日期是否满足:
- 记录的
OpenDate早于当前日期 - 记录的
CloseDate(为空则用2050-01-01替代)晚于当前日期 - 记录的
CloseType属于集合{0, 1, 3, 7, 8}
- 记录的
- 所有满足条件的日期与原记录组合,最终输出结构为:
CurrentDate | User_Id | OpenDate | CloseDate | CloseType的新DataFrame
基于Pandas的高效实现方案
下面是具体可运行的Python代码,步骤清晰且比手动循环更高效:
1. 导入依赖并准备基础数据
import pandas as pd from datetime import datetime # 生成日期范围(用Pandas内置方法替代手动循环,简洁高效) start = datetime(2024, 6, 1) end = datetime(2024, 12, 10) dates_df = pd.date_range(start=start, end=end).to_frame(name='CurrentDate') # 你的样本DataFrame(真实场景中可替换为读取的数据源) raw_df = pd.DataFrame([ [12, '2022-02-14', '2022-02-18', 3], [14, '2021-12-26', '2021-12-26', 6], [34, '2022-05-22', '2022-06-12', 3], [93, '2021-12-06', '2021-12-06', 6] ], columns=['User_Id', 'OpenDate', 'CloseDate', 'CloseType'])
2. 统一日期类型,确保可正常比较
# 将所有日期列转为datetime类型,避免字符串比较的问题 raw_df['OpenDate'] = pd.to_datetime(raw_df['OpenDate']) raw_df['CloseDate'] = pd.to_datetime(raw_df['CloseDate']) dates_df['CurrentDate'] = pd.to_datetime(dates_df['CurrentDate'])
3. 生成原始数据与日期的全组合(交叉连接)
# 通过临时key实现交叉连接,得到每条记录和每个日期的所有可能组合 raw_df['temp_key'] = 1 dates_df['temp_key'] = 1 cross_joined_df = pd.merge(raw_df, dates_df, on='temp_key').drop('temp_key', axis=1)
4. 应用过滤条件(完全对应你的SQL逻辑)
# 填充空CloseDate为2050-01-01,对应SQL的ISNULL逻辑 cross_joined_df['filled_close_date'] = cross_joined_df['CloseDate'].fillna(pd.to_datetime('2050-01-01')) # 应用过滤条件 filtered_df = cross_joined_df[ (cross_joined_df['OpenDate'] < cross_joined_df['CurrentDate']) & (cross_joined_df['filled_close_date'] > cross_joined_df['CurrentDate']) & (cross_joined_df['CloseType'].isin([0, 1, 3, 7, 8])) ]
5. 整理最终结果格式
# 按需将日期转为字符串格式(也可保留datetime类型) filtered_df['CurrentDate'] = filtered_df['CurrentDate'].dt.strftime('%Y-%m-%d') filtered_df['OpenDate'] = filtered_df['OpenDate'].dt.strftime('%Y-%m-%d') filtered_df['CloseDate'] = filtered_df['CloseDate'].dt.strftime('%Y-%m-%d') # 调整列顺序并移除临时列 final_df = filtered_df[['CurrentDate', 'User_Id', 'OpenDate', 'CloseDate', 'CloseType']] # 查看结果 print(final_df.head())
注意事项
你的样本数据中所有记录的CloseDate都早于2024-06-01(日期范围的起始日),因此按照条件不会筛选出任何结果。如果真实数据中有CloseDate晚于2024-06-01或为空的记录,就能得到符合要求的组合。
备注:内容来源于stack exchange,提问作者lpca
相关产品推荐
相关产品推荐

