在Pandas中高效地根据日期条件提取和填充数据

在Pandas中高效地根据日期条件提取和填充数据

本教程将指导您如何在pandas dataframe中根据特定日期条件高效地提取列值,并在不满足条件时填充nan。文章将对比低效的循环方法与pandas推荐的矢量化解决方案,如使用series.where()和部分字符串索引,强调性能优化和正确的日期处理技巧。

在数据分析工作中,我们经常需要根据DataFrame索引(特别是DatetimeIndex)中的特定日期或日期范围来提取或修改数据。一个常见的需求是,当索引匹配特定日期时,从另一列获取值;否则,填充NaN。本文将深入探讨实现这一目标的几种方法,并重点推荐Pandas的矢量化解决方案,以确保代码的效率和可读性。

1. 避免低效的循环操作

初学者可能会倾向于使用Python的for循环和iterrows()来遍历DataFrame的每一行。虽然这种方法在某些情况下是直观的,但对于大型数据集而言,它的性能非常低下,并且容易导致逻辑错误。

考虑以下一个常见的错误尝试:

import pandas as pdimport numpy as np# 示例DataFrame,索引包含时间信息rng = pd.date_range('2000-03-19', periods=10, freq='9H')df = pd.DataFrame({'close': range(10)}, index=rng)# 错误的循环方法# for index, row in df.iterrows():#     if index == '2000-03-20 00:00:00': # 注意:这里如果索引包含时间,直接比较可能不匹配#         df['event'] = row['close'] # 错误:这会覆盖整个'event'列#     else:#         df['event'] = float('nan') # 错误:这也会覆盖整个'event'列# print(df)# 结果:'event' 列可能全部是 NaN,或者只保留了最后一次循环的赋值# 修正后的循环(仍不推荐)df_loop_fixed = df.copy() # 使用副本进行演示,避免修改原始dffor index, row in df_loop_fixed.iterrows():    # 匹配日期部分,忽略时间,并将索引标准化为午夜    if index.normalize() == pd.Timestamp('2000-03-20').normalize():        df_loop_fixed.loc[index, 'event'] = row['close'] # 正确:使用loc按索引赋值    else:        df_loop_fixed.loc[index, 'event'] = np.nan # 正确:使用loc按索引赋值print("修正后的循环结果 (不推荐):")print(df_loop_fixed)

问题分析与改进:原始的循环代码 df[‘event’] = … 每次迭代都会将整个 event 列赋值为一个单一值,导致之前的所有赋值被覆盖。正确的做法是使用 df.loc[index, ‘column_name’] = value 来针对特定行和列进行赋值。此外,如果索引包含时间信息而我们只想匹配日期,则需要对索引和目标日期都使用 normalize() 方法来移除时间部分。

尽管上述修正后的循环能够得到正确的结果,但由于Python循环的开销,它在大规模数据集上的执行效率非常低。在Pandas中,我们应该优先使用矢量化操作。

2. 矢量化解决方案(推荐)

Pandas提供了多种高效的矢量化方法来处理此类条件赋值任务,它们在底层使用优化的C语言实现,性能远超Python循环。

2.1 使用 Series.where() 方法

Series.where(cond, other=NaN) 方法是实现条件赋值的理想选择。它会根据布尔条件 cond 返回一个与原Series相同大小的Series。当 cond 为 True 时,保留原Series的值;当 cond 为 False 时,填充 other 指定的值(默认为 NaN)。

场景一:精确匹配完整时间戳

如果您的DataFrame索引是精确到秒的时间戳,并且您希望精确匹配某个时间点:

Stable Diffusion 2.1 Demo Stable Diffusion 2.1 Demo

最新体验版 Stable Diffusion 2.1

Stable Diffusion 2.1 Demo 101 查看详情 Stable Diffusion 2.1 Demo

# 示例DataFrame,索引每日一个数据点rng_daily = pd.date_range('2000-03-19', periods=10, freq='D')df_daily = pd.DataFrame({'close': range(10)}, index=rng_daily)# 精确匹配 '2000-03-20 00:00:00'df_daily['event_exact'] = df_daily['close'].where(df_daily.index == pd.Timestamp('2000-03-20 00:00:00'))print("n使用 Series.where() 进行精确时间戳匹配:")print(df_daily)

场景二:仅匹配日期,忽略时间部分

在许多情况下,我们的 DatetimeIndex 可能包含时间信息(如小时、分钟、秒),但我们只关心日期部分。这时可以使用 DatetimeIndex.normalize() 方法,它会将每个时间戳的时间部分设置为午夜(00:00:00),从而只保留日期信息。

# 示例DataFrame,索引包含时间信息rng_with_time = pd.date_range('2000-03-19', periods=10, freq='9H')df_time = pd.DataFrame({'close': range(10)}, index=rng_with_time)# 匹配 '2000-03-20' 这一整天,忽略时间df_time['event_daily'] = df_time['close'].where(df_time.index.normalize() == pd.Timestamp('2000-03-20').normalize())print("n使用 Series.where() 仅匹配日期,忽略时间:")print(df_time)

在这个例子中,所有日期为 2000-03-20 的行,无论其具体时间如何,event_daily 列都会取 close 列的值。

2.2 使用部分字符串索引 (Partial String Indexing)

Pandas的 DatetimeIndex 支持非常便捷的部分字符串索引功能。您可以使用日期字符串(如 ‘YYYY-MM-DD’)直接选择一个日期或日期范围内的所有行。结合 loc 索引器,这成为一种非常简洁高效的条件赋值方式。

首先,初始化目标列为 NaN,然后对特定日期进行赋值:

# 重新创建DataFrame以确保event列初始为NaNdf_partial = pd.DataFrame({'close': range(10)}, index=rng_with_time)df_partial['event_partial'] = np.nan # 初始化为NaN,以确保非匹配项为NaN# 使用部分字符串索引对 '2000-03-20' 这一天的所有行赋值# df_partial.loc['2000-03-20'] 会选择所有日期为2000-03-20的行df_partial.loc['2000-03-20', 'event_partial'] = df_partial.loc['2000-03-20', 'close']print("n使用部分字符串索引进行赋值:")print(df_partial)

这种方法非常简洁,尤其适用于您希望将特定日期范围内的所有行的某个列值设置为另一个列的值时。它会自动处理所有匹配该日期字符串的索引条目,无论是精确匹配还是包含时间的部分匹配。

3. 总结与注意事项

矢量化优先: 在Pandas中处理大规模数据时,始终优先考虑使用矢量化操作(如 Series.where()、布尔索引等),而不是Python的循环。矢量化操作通常在底层使用C语言实现,效率远高于Python循环。日期匹配精度:如果需要精确匹配包含时间的时间戳,直接比较 df.index == pd.Timestamp(…)。如果只需要匹配日期部分,忽略时间,使用 df.index.normalize() == pd.Timestamp(…).normalize()。部分字符串索引 (df.loc[‘YYYY-MM-DD’]) 在匹配日期时非常方便,它会自动涵盖该日期的所有时间点。NaN 的处理: 使用 numpy.nan 或 float(‘nan’) 来表示缺失值是Pandas的惯例。loc 和 iloc 的正确使用: 在进行基于标签(如日期、列名)的赋值时,使用 loc;在进行基于整数位置的赋值时,使用 iloc。避免链式索引赋值,因为它可能返回视图而不是副本,导致 SettingWithCopyWarning 或意外行为。

通过掌握这些高效的Pandas技巧,您将能够更专业、更高效地处理时间序列数据中的条件赋值任务。

以上就是在Pandas中高效地根据日期条件提取和填充数据的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/918593.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
桃源深处有人家兑换码2025
上一篇 2025年11月29日 06:38:55
安卓15 Beta 2更新:Overflow音量菜单焕然一新
下一篇 2025年11月29日 06:39:00

相关推荐

  • 如何在Python在线编辑器中实现input与后台交互?

    在在线Python编辑器中实现input与后台交互 许多在线Python编辑器并不直接支持input()函数的交互式功能。要实现类似功能,需要借助后端语言(例如PHP)作为桥梁。 实现方法: 前端修改:将input替换为textarea。 由于input元素通常只接受单行文本,不适合多行Python…

    2026年5月10日
    000
  • c++ map如何插入和查找键值对_c++ map插入与查找方法

    std::map基于红黑树实现,支持自动排序,插入和查找时间复杂度为O(log n)。1. 插入可用insert、下标[]或emplace,其中emplace效率更高;2. 查找推荐使用find或count,避免用下标导致意外插入;3. 示例展示了三种插入与两种查找方法的正确使用场景。 在C++中,…

    2026年5月10日
    000
  • 如何用Golang实现第一个CLI工具 详解cobra库创建命令行应用

    如何用Golang实现第一个CLI工具 详解cobra库创建命令行应用如何用Golang实现第一个CLI工具 详解cobra库创建命令行应用如何用Golang实现第一个CLI工具 详解cobra库创建命令行应用如何用Golang实现第一个CLI工具 详解cobra库创建命令行应用

    用golang实现cli工具可借助cobra库快速完成。1. 安装cobra:使用go install github.com/spf13/cobra-cli@latest;2. 初始化项目结构:运行cobra init –pkg-name mycli生成基础代码;3. 添加子命令:执行c…

    2026年5月10日 用户投稿
    000
  • 怎样用Python处理视频流?OpenCV帧操作详解

    怎样用Python处理视频流?OpenCV帧操作详解怎样用Python处理视频流?OpenCV帧操作详解怎样用Python处理视频流?OpenCV帧操作详解怎样用Python处理视频流?OpenCV帧操作详解

    python和opencv处理视频流的核心在于将视频拆分为帧并逐帧处理。步骤包括:1. 捕获视频源,使用cv2.videocapture()打开摄像头或视频文件;2. 循环读取每一帧并判断是否成功获取;3. 对每一帧进行图像处理操作,如灰度化、模糊、边缘检测等;4. 显示或保存处理后的帧;5. 最后…

    2026年5月10日 用户投稿
    000
  • JavaScriptTC39标准_JavaScript语言规范解读

    TC39通过五阶段流程推动JavaScript发展,确保语言在兼容基础上持续进化,近年引入可选链、空值合并、顶级await等特性,并推进记录与元组、装饰器等提案,开发者可通过GitHub跟踪进展并用Babel实验新功能。 JavaScript语言的发展离不开TC39组织的推动。TC39是负责ECMA…

    2026年5月10日
    000
  • python和pycharm区别是什么

    区别是:1、Python是一种编程语言,而PyCharm是一款用于Python开发的集成开发环境;2、可以使用PyCharm来编写、调试和管理Python代码,而Python则是在PyCharm中使用的编程语言。 本教程操作系统:windows10系统、Python3.11.4版本、Dell G3电…

    2026年5月10日
    000
  • ThinkPHP框架怎么使用验证器_ThinkPHP数据验证规则与场景配置

    ThinkPHP验证器用于数据校验,提升系统健壮性。通过继承thinkValidate创建自定义验证器,如UserValidate定义用户名、邮箱、密码规则及提示信息;在控制器中实例化并调用check方法进行验证,失败返回错误信息。内置丰富规则:require(必填)、number/integer(…

    2026年5月10日
    100
  • Go语言:通过进程名检查进程运行状态的实用方法

    在Go语言中,标准库并未直接提供通过进程名称查询其运行状态的API。本文将详细介绍两种主要方法:一是利用os/exec包调用系统命令行工具(如pgrep或pidof),这在类Unix系统中高效便捷;二是探讨解析/proc文件系统(procfs)的原理,这为Linux环境提供了一种更底层、无需外部命令…

    2026年5月10日
    100
  • c语言中x-是什么意思

    C 语言中,x- 表示按位取反运算符,将二进制位中的 0 变成 1,1 变成 0。它作用于一个操作数,语法为 ~,应用场景包括创建掩码清除特定值、转换整数为二进制补码和进行位级转换。 C 语言中 x- 的含义 在 C 语言中,x- 表示按位取反运算符。其作用是将表达式或变量中的每个二进制位取反,也就…

    2026年5月10日
    000
  • C++如何实现建造者 C++建造者模式的设计

    C++如何实现建造者 C++建造者模式的设计C++如何实现建造者 C++建造者模式的设计C++如何实现建造者 C++建造者模式的设计C++如何实现建造者 C++建造者模式的设计

    建造者模式与工厂模式的区别在于,工厂模式用于创建不同类型的对象,而建造者模式专注于构建复杂对象的不同部分。1. 工厂模式通常一步返回完整对象;2. 建造者模式允许逐步构建并控制过程;3. 建造者适用于对象构建复杂、需灵活配置组件的情况;4. 建造者避免构造函数臃肿,提高可维护性;5. c++++中通…

    2026年5月10日 用户投稿
    000
  • 深入理解Go语言:方法接收者与参数的本质区别与应用

    在go语言中,方法接收者与普通函数参数在语法和语义上存在显著差异。接收者是一种特殊的参数,用于将方法绑定到特定类型,从而实现类似面向对象的行为,允许通过类型实例直接调用方法。它本质上是go提供的一种语法糖,使得代码更具可读性和结构性。 Go语言作为一门静态类型语言,提供了强大的函数和方法机制。理解它…

    2026年5月10日
    000
  • Python的基础知识

    python:入门指南及第一个程序 Python以其易用性和强大的功能而闻名,广泛应用于网络开发、数据科学、人工智能和自动化等领域。无论是编程新手还是经验丰富的开发者,Python都是一个理想的选择。 安装Python 在开始编写Python代码之前,您需要先在系统上安装Python。 步骤一:下载…

    2026年5月10日
    000
  • 如何安装Python OpenCV 2.4.9版本? 或者 Python OpenCV 2.4.9版本安装遇到问题怎么办?

    python opencv 2.4.9版本安装详解及问题解决 许多Python开发者在图像处理和计算机视觉项目中使用OpenCV。虽然pip install opencv-python 能轻松安装最新版本,但有时需要特定版本,例如OpenCV 2.4.9。本文将指导您如何安装此版本,并解决可能遇到的…

    2026年5月10日
    000
  • C++20的同步原语latch和barrier怎么用_C++多线程编程中的栅栏同步机制

    latch是一次性同步工具,用于等待计数归零后释放所有线程,适用于单次等待场景;barrier支持重复使用,允许多轮同步,适合周期性或分阶段的并行任务。 在C++20中,latch 和 barrier 是新增的两种同步原语,用于简化多线程编程中的等待逻辑。它们都属于“栅栏”类同步机制,但用途和行为有…

    2026年5月10日
    000
  • python时间戳怎么获取

    在 Python 中,获取时间戳有两种方法:使用 time.time() 获取从纪元时间到当前时间经过的秒数;使用 datetime.datetime.now().timestamp() 获取当前时间戳,精度为微秒。 如何获取 Python 时间戳 在 Python 中,获取时间戳有两种主要方法: …

    2026年5月10日
    000
  • Go语言中高效读取大尺寸UTF-8字符串:使用bufio优化输入操作

    在Go语言中处理大尺寸UTF-8字符串输入时,fmt.Scanf因其非缓冲特性和解析开销可能导致显著的性能瓶颈。本文将介绍如何利用bufio包实现高效、纯Go的字符串读取方案。通过使用bufio.NewReader及其方法,如ReadString,可以大幅提升输入操作的速度,甚至超越C语言scanf…

    2026年5月10日
    000
  • 如何使用正则表达式从XML中提取特定标签内容?

    使用正则表达式提取xml内容存在局限性,不推荐用于复杂场景。1. 难以处理嵌套结构:正则表达式无法可靠匹配多层嵌套标签;2. 容易出错:xml格式的微小变化可能导致匹配失败;3. 可读性差:复杂正则难以理解和维护;4. 不支持xml所有特性:如命名空间、cdata等难以正确处理。相比之下,使用xml…

    2026年5月10日
    000
  • Go语言调用Windows API:获取Windows系统字体文件夹路径

    本文详细介绍了如何使用go语言调用windows api `shgetknownfolderpath` 来获取系统字体文件夹的准确路径。通过`syscall`包实现对`shell32.dll`和`ole32.dll`的调用,文章涵盖了`guid`结构体的定义、api函数签名的适配、内存管理(`cot…

    2026年5月10日
    100
  • 如何使用Golang反射设置结构体默认值

    通过反射和标签可为Golang结构体字段设置默认值,需传入指针并检查字段是否导出及为空,结合default标签实现自动填充。 在 Golang 中,可以通过反射(reflect)动态地为结构体字段设置默认值。这在处理配置解析、数据库映射或 API 请求参数时非常有用。下面介绍如何使用反射遍历结构体字…

    2026年5月10日
    000
  • 如何在Golang中处理异步HTTP请求

    答案:Golang中通过goroutine、channel和context实现异步HTTP请求,利用goroutine并发执行http.Get等操作,通过channel传递结果并控制并发数,结合context实现超时与取消,可封装为返回 在Golang中处理异步HTTP请求,核心是利用gorouti…

    2026年5月10日
    000

发表回复

登录后才能评论
关注微信