0

0

使用 Pandas 基于日期范围条件填充 DataFrame

DDD

DDD

发布时间:2025-10-18 13:32:01

|

841人浏览过

|

来源于php中文网

原创

使用 Pandas 基于日期范围条件填充 DataFrame

本教程详细介绍了如何使用 pandas 在两个 dataframe 之间进行条件性数据填充。通过将一个 dataframe 的数据根据另一个 dataframe 定义的日期范围进行筛选和合并,最终生成一个符合特定日期范围要求的新 dataframe。核心方法包括日期类型转换、数据重塑(`melt`)、基于日期索引的近似合并(`merge_asof`)以及条件性数据筛选和透视(`pivot`),旨在高效处理复杂的时序数据关联任务。

在数据分析和处理中,我们经常会遇到需要根据特定条件从一个数据集中提取或填充另一个数据集的场景。特别是当条件涉及日期范围时,操作会变得更加复杂。本教程将展示如何利用 Pandas 库的强大功能,实现根据一个 DataFrame 定义的日期范围,从另一个 DataFrame 中有条件地填充数据。

场景描述

假设我们有两个 DataFrame:

  1. df1:包含公司及其对应的有效日期范围(start date 和 end date)。
  2. df2:包含按日期和公司分组的实际数据。

我们的目标是创建一个新的 DataFrame (df3),其中 df2 中的数据仅在 df1 定义的相应公司的日期范围内才有效。超出范围的数据应显示为 NaN。

示例输入数据:

import pandas as pd

# df1: 定义日期范围
data1 = {'company': {0: 'a', 1: 'b', 2: 'c', 3: 'd'},
         'start date': {0: '2023-01-02', 1: '2023-01-05', 2: '2023-01-04', 3: '2023-01-03'},
         'end date': {0: '2023-01-06', 1: '2023-01-12', 2: '2023-01-13', 3: '2023-01-10'}}
df1 = pd.DataFrame(data1)

# df2: 原始数据
data2 = {'DATE': {0: '2023-01-02', 1: '2023-01-03', 2: '2023-01-04', 3: '2023-01-05',
                  4: '2023-01-06', 5: '2023-01-09', 6: '2023-01-10', 7: '2023-01-11',
                  8: '2023-01-12', 9: '2023-01-13'},
         'a': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10},
         'b': {0: 10, 1: 11, 2: 12, 3: 13, 4: 14, 5: 15, 6: 16, 7: 17, 8: 18, 9: 19},
         'c': {0: 30, 1: 31, 2: 32, 3: 33, 4: 34, 5: 35, 6: 36, 7: 37, 8: 38, 9: 39},
         'd': {0: 40, 1: 41, 2: 42, 3: 43, 4: 44, 5: 45, 6: 46, 7: 47, 8: 48, 9: 49}}
df2 = pd.DataFrame(data2)

print("df1:")
print(df1)
print("\ndf2:")
print(df2)

步骤一:日期列类型转换

在进行任何日期相关的操作之前,确保所有日期列都被正确识别为 datetime 类型至关重要。这可以防止潜在的类型不匹配错误,并允许使用 Pandas 强大的日期时间功能。

df1['start date'] = pd.to_datetime(df1['start date'])
df1['end date'] = pd.to_datetime(df1['end date'])
df2['DATE'] = pd.to_datetime(df2['DATE'])

print("\ndf1 (after type conversion):")
print(df1)
print("\ndf2 (after type conversion):")
print(df2)

步骤二:数据重塑、合并与条件筛选

这一步是解决方案的核心,它涉及将数据从宽格式转换为长格式,执行近似合并,然后应用日期范围条件进行筛选。

  1. 数据重塑 (melt): df2 当前是宽格式,每个公司有一列。为了能按公司和日期与 df1 进行合并,我们需要将其转换为长格式,即每行包含 DATE、company 和 value。

    df2_melted = df2.melt('DATE', var_name='company', value_name='value')
    # 打印部分结果以理解 melt 的作用
    # print("\ndf2_melted (partial):")
    # print(df2_melted.head())
  2. 数据排序: merge_asof 要求其左侧和右侧的 DataFrame 都必须按合并键进行排序。对于我们的场景,df2_melted 需要按 DATE 排序,df1 需要按 start date 排序。

    甲骨文AI协同平台
    甲骨文AI协同平台

    专门用于甲骨文研究的革命性平台

    下载
    df2_melted_sorted = df2_melted.sort_values('DATE')
    df1_sorted = df1.sort_values('start date')
  3. 近似合并 (merge_asof): merge_asof 是一个强大的工具,用于执行“as of”合并,即在左 DataFrame 的键值大于或等于右 DataFrame 的键值时,合并最近的行。在这里,我们希望将 df2_melted 中的每个 DATE 与 df1 中对应的 company 的 start date 进行匹配。

    • left_on='DATE':df2_melted 的合并键。
    • right_on='start date':df1 的合并键。
    • by='company':确保仅在相同的 company 下进行合并。
    tmp = pd.merge_asof(df2_melted_sorted,
                        df1_sorted,
                        by='company',
                        left_on='DATE',
                        right_on='start date')
    # print("\ntmp (after merge_asof, partial):")
    # print(tmp.head(10))

    此时,tmp DataFrame 包含了 df2 的原始值,以及从 df1 合并过来的 start date 和 end date。重要的是,merge_asof 确保了 DATE >= start date。

  4. 条件性数据筛选 (where): merge_asof 已经确保了 DATE 不早于 start date。现在,我们还需要确保 DATE 不晚于 end date。我们可以使用 DataFrame.where() 方法,它会根据条件保留值,不满足条件的则替换为 NaN。

    tmp['value'] = tmp['value'].where(tmp['DATE'].le(tmp['end date']))
    # print("\ntmp (after conditional filtering, partial):")
    # print(tmp.head(10))
  5. 数据透视 (pivot): 最后,我们将处理后的 tmp DataFrame 从长格式重新透视回我们期望的宽格式,其中 DATE 作为索引,company 作为列,value 作为数据。

    df3 = tmp.pivot(index='DATE', columns='company', values='value')\
             .rename_axis('', axis=1)\
             .reset_index()

完整代码示例

将上述所有步骤整合,得到完整的解决方案:

import pandas as pd

# 1. 准备数据
data1 = {'company': {0: 'a', 1: 'b', 2: 'c', 3: 'd'},
         'start date': {0: '2023-01-02', 1: '2023-01-05', 2: '2023-01-04', 3: '2023-01-03'},
         'end date': {0: '2023-01-06', 1: '2023-01-12', 2: '2023-01-13', 3: '2023-01-10'}}
df1 = pd.DataFrame(data1)

data2 = {'DATE': {0: '2023-01-02', 1: '2023-01-03', 2: '2023-01-04', 3: '2023-01-05',
                  4: '2023-01-06', 5: '2023-01-09', 6: '2023-01-10', 7: '2023-01-11',
                  8: '2023-01-12', 9: '2023-01-13'},
         'a': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10},
         'b': {0: 10, 1: 11, 2: 12, 3: 13, 4: 14, 5: 15, 6: 16, 7: 17, 8: 18, 9: 19},
         'c': {0: 30, 1: 31, 2: 32, 3: 33, 4: 34, 5: 35, 6: 36, 7: 37, 8: 38, 9: 39},
         'd': {0: 40, 1: 41, 2: 42, 3: 43, 4: 44, 5: 45, 6: 46, 7: 47, 8: 48, 9: 49}}
df2 = pd.DataFrame(data2)

# 2. 日期列类型转换
df1['start date'] = pd.to_datetime(df1['start date'])
df1['end date'] = pd.to_datetime(df1['end date'])
df2['DATE'] = pd.to_datetime(df2['DATE'])

# 3. 数据重塑、合并与条件筛选
# 将 df2 从宽格式转换为长格式,便于按公司合并
df2_melted = df2.melt('DATE', var_name='company', value_name='value')

# 对两个 DataFrame 进行排序,以满足 merge_asof 的要求
df2_melted_sorted = df2_melted.sort_values('DATE')
df1_sorted = df1.sort_values('start date')

# 使用 merge_asof 进行近似合并,按公司和日期进行匹配
# left_on='DATE' 和 right_on='start date' 确保 DATE >= start date
tmp = pd.merge_asof(df2_melted_sorted,
                    df1_sorted,
                    by='company',
                    left_on='DATE',
                    right_on='start date')

# 应用第二个日期范围条件:确保 DATE <= end date
# 不满足条件的 'value' 将被设置为 NaN
tmp['value'] = tmp['value'].where(tmp['DATE'].le(tmp['end date']))

# 将结果从长格式透视回宽格式
df3 = tmp.pivot(index='DATE', columns='company', values='value')\
         .rename_axis('', axis=1)\
         .reset_index()

print("\nDesired Output (df3):")
print(df3)

注意事项与总结

  1. 日期类型的重要性: 始终确保日期列为 datetime 类型。这是 Pandas 进行日期比较和 merge_asof 操作的基础。
  2. melt 的作用: melt 函数将宽格式数据转换为长格式,这在进行多条件(例如,按公司和日期)合并时非常有用,因为它将公司名称从列名转换为可用于合并的实际数据。
  3. merge_asof 的特性: merge_asof 执行的是“as of”合并,即对于左侧 DataFrame 中的每一行,它会查找右侧 DataFrame 中最近的、不大于左侧键值的行。在本例中,我们利用 left_on='DATE' 和 right_on='start date' 来确保合并的行满足 DATE >= start date 的条件。
  4. 排序要求: merge_asof 要求两个待合并的 DataFrame 都必须根据合并键进行排序。
  5. where 的应用: DataFrame.where() 方法提供了一种简洁高效的方式来根据条件替换 DataFrame 中的值,非常适合我们根据 end date 进行二次筛选的需求。
  6. pivot 的逆操作: pivot 是 melt 的逆操作,它将长格式数据重新转换为宽格式,生成最终所需的输出结构。

通过以上步骤,我们成功地利用 Pandas 实现了根据日期范围条件从一个 DataFrame 填充另一个 DataFrame 的复杂数据处理任务。这种方法灵活且高效,适用于各种需要基于时间范围进行数据关联和筛选的场景。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

82

2025.12.04

Python 数据清洗与预处理实战
Python 数据清洗与预处理实战

本专题系统讲解 Python 在数据清洗与预处理中的核心技术,包括使用 Pandas 进行缺失值处理、异常值检测、数据格式化、特征工程与数据转换,结合 NumPy 高效处理大规模数据。通过实战案例,帮助学习者掌握 如何处理混乱、不完整数据,为后续数据分析与机器学习模型训练打下坚实基础。

34

2026.01.31

C++类型转换方式
C++类型转换方式

本专题整合了C++类型转换相关内容,想了解更多相关内容,请阅读专题下面的文章。

321

2025.07.15

Python WebSocket实时通信与异步服务开发实践
Python WebSocket实时通信与异步服务开发实践

本专题聚焦 Python 在实时通信场景中的开发实践,系统讲解 WebSocket 协议原理、长连接管理、消息推送机制以及异步服务架构设计。内容包括客户端与服务端通信实现、连接稳定性优化、消息队列集成及高并发处理策略。通过完整案例,帮助开发者构建高效稳定的实时通信系统,适用于聊天应用、实时数据推送等场景。

5

2026.03.18

Java Spring Security权限控制与认证机制实战
Java Spring Security权限控制与认证机制实战

本专题围绕 Java 后端安全体系建设展开,重点讲解 Spring Security 在权限控制与认证机制中的应用实践。内容涵盖用户认证流程、权限模型设计、JWT 鉴权方案、OAuth2 集成以及接口安全防护策略。通过实际项目案例,帮助开发者构建安全可靠的后端认证体系,提升系统安全性与可扩展能力。

21

2026.03.18

抖漫入口地址合集
抖漫入口地址合集

本专题整合了抖漫入口地址相关合集,阅读专题下面的文章了解更多详细地址。

137

2026.03.17

多环境下的 Nginx 安装、结构与运维实战
多环境下的 Nginx 安装、结构与运维实战

本专题聚焦多环境下Nginx实战,详解开发、测试及生产环境的差异化安装策略与目录结构规划。深入剖析配置模块化设计、灰度发布流程及跨环境同步机制。结合监控告警、故障排查与自动化运维工具,提供全链路管理方案,助力团队构建灵活、高可用的Nginx服务体系,从容应对复杂业务场景挑战。

14

2026.03.17

PS 批量添加图片
PS 批量添加图片

本专题整合了PS批量添加图片教程合集,阅读专题下面的文章了解更多详细操作。

14

2026.03.17

Nginx 基础架构:从安装配置到系统化管理
Nginx 基础架构:从安装配置到系统化管理

本专题深入解析Nginx基础架构,涵盖从源码编译与包管理安装,到核心配置文件优化及虚拟主机部署。进一步探讨日志轮转、性能调优、高可用集群构建及自动化运维策略,助力管理员实现从单一服务搭建到企业级系统化管理的全面升级,确保Web服务高效、稳定运行。

7

2026.03.17

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 6.2万人学习

ASP 教程
ASP 教程

共34课时 | 6.1万人学习

Vue3.x 工具篇--十天技能课堂
Vue3.x 工具篇--十天技能课堂

共26课时 | 1.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号