0

0

Pandas高效计算基于分类列变化的滚动时间差

碧海醫心

碧海醫心

发布时间:2025-10-13 10:07:18

|

660人浏览过

|

来源于php中文网

原创

Pandas高效计算基于分类列变化的滚动时间差

本文详细介绍了如何在pandas dataframe中高效计算一个时间列相对于另一个分类列每次变化时的累积时间差。通过利用`groupby.transform('first')`和`shift().cumsum()`等向量化操作,避免了低效的循环,实现了在分类变量连续值块内,从该块起始点开始计算时间增量,从而生成精确的滚动时间差序列。

在数据分析中,我们经常会遇到需要根据某一列的值变化来计算另一列的累积量或差值的情况。例如,在一个包含时间序列数据的DataFrame中,如果有一个分类列表示不同的状态或事件,我们可能需要计算从该分类列上一次状态改变开始到当前时间点所经过的时间。本文将探讨如何使用Pandas高效地解决这类问题,避免使用性能低下的循环。

问题描述

假设我们有一个Pandas DataFrame,结构如下:

A t X
1 0.0 0
1 3.2 3.2
1 3.9 3.9
1 18.0 18
1 27.4 27.4
3 47.4 0
3 50.2 2.9
3 57.2 9.8
3 64.8 17.4
3 76.4 29.1
2 80.5 0
1 85.3 0
1 87.4 2.1

其中:

  • A 是一个分类变量,表示不同的类别或状态。
  • t 是一个时间戳(以秒为单位)。
  • X 是我们希望计算的输出列,它表示从列 A 的值上一次发生变化以来所经过的秒数。当 A 的值首次出现或发生变化时,X 的值应为0。

直观的解决方案可能是使用一个for循环遍历DataFrame,并在A列值改变时重置计数器。然而,对于大型数据集,这种方法计算成本高昂且效率低下。我们需要一个更符合Pandas哲学,即利用向量化操作的解决方案。

Pandas高效解决方案

解决此问题的关键在于识别 A 列中连续相同值的“块”或“组”,然后对每个组内的 t 列进行操作。Pandas提供了强大的工具来完成这项任务。

步骤一:识别连续值组

首先,我们需要为 A 列中每个连续的相同值块创建一个唯一的标识符。这可以通过以下组合操作实现:

  1. df['A'].shift():将 A 列向下移动一行,以便与当前行进行比较。
  2. df['A'].ne(df['A'].shift()):比较当前行 A 的值是否不等于上一行 A 的值。这将返回一个布尔序列,其中 True 表示 A 的值发生了变化,False 表示值保持不变。
  3. .cumsum():对布尔序列进行累积求和。由于 True 在数值上下文中被视为1,False 被视为0,cumsum() 会在每次 A 的值发生变化时递增计数器,从而为每个连续的相同值块生成一个唯一的组ID。
import pandas as pd

# 示例数据
data = {
    'A': [1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 2, 1, 1],
    't': [0.0, 3.2, 3.9, 18.0, 27.4, 47.4, 50.2, 57.2, 64.8, 76.4, 80.5, 85.3, 87.4]
}
df = pd.DataFrame(data)

# 生成连续值组的标识符
group = df['A'].ne(df['A'].shift()).cumsum()
print("生成的组标识符:")
print(group)

输出的 group 序列将如下所示:

Thiings
Thiings

免费的拟物化图标库

下载
生成的组标识符:
0     1
1     1
2     1
3     1
4     1
5     2
6     2
7     2
8     2
9     2
10    3
11    4
12    4
Name: A, dtype: int64

可以看到,当 A 从 1 变为 3 时,组ID从 1 变为 2;当 A 从 3 变为 2 时,组ID从 2 变为 3,以此类推。

步骤二:计算组内时间差

有了组标识符后,我们就可以对每个组内的 t 值进行操作。目标是计算每个 t 值与该组内第一个 t 值之间的差。

  1. df.groupby(group)['t']:根据上一步生成的 group 标识符对 t 列进行分组。
  2. .transform('first'):这是关键一步。transform('first') 会对每个组应用 first 函数(即获取组内的第一个值),然后将结果广播回原始DataFrame的形状,确保每个原始行都对应其所在组的第一个 t 值。
  3. df['t'].sub(...):最后,用原始的 t 列减去广播回来的组内第一个 t 值,即可得到所需的滚动时间差 X。
# 计算X列
df['X'] = df['t'].sub(df.groupby(group)['t'].transform('first'))

print("\n最终结果DataFrame:")
print(df)

完整代码示例

将上述步骤整合到一起,完整的解决方案如下:

import pandas as pd

# 示例数据
data = {
    'A': [1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 2, 1, 1],
    't': [0.0, 3.2, 3.9, 18.0, 27.4, 47.4, 50.2, 57.2, 64.8, 76.4, 80.5, 85.3, 87.4]
}
df = pd.DataFrame(data)

# 步骤1: 生成连续值组的标识符
group = df['A'].ne(df['A'].shift()).cumsum()

# 步骤2: 计算X列,即当前t值减去该组的第一个t值
df['X'] = df['t'].sub(df.groupby(group)['t'].transform('first'))

print(df)

输出结果

    A      t      X
0   1    0.0    0.0
1   1    3.2    3.2
2   1    3.9    3.9
3   1   18.0   18.0
4   1   27.4   27.4
5   3   47.4    0.0
6   3   50.2    2.8
7   3   57.2    9.8
8   3   64.8   17.4
9   3   76.4   29.0
10  2   80.5    0.0
11  1   85.3    0.0
12  1   87.4    2.1

从输出结果可以看到,X 列准确地反映了从 A 列值上一次变化(即当前组的起始点)开始所经过的时间。例如,在索引5处,A 从 1 变为 3,X 被重置为 0.0。在索引6处,t 为 50.2,该组的起始 t 值为 47.4,所以 X 为 50.2 - 47.4 = 2.8。

注意事项与总结

  • 效率优势: 这种方法完全依赖于Pandas的向量化操作,避免了Python的显式循环,因此在大数据集上具有显著的性能优势。
  • transform 的作用: groupby().transform() 方法非常强大,它将一个聚合函数(如 first, mean, sum 等)应用于每个组,并将结果广播回原始DataFrame的索引,保持了DataFrame的形状,这与 groupby().apply() 或 groupby().agg() 的行为不同,后者通常会改变DataFrame的形状。
  • 适用性: 这种模式不仅适用于时间差计算,还可以用于计算每个组内的累积和、平均值、最大值等,只要你需要将组级别的聚合结果映射回原始行的场景。
  • 处理 NaN 值: shift() 操作会在第一行引入 NaN。ne() 操作会正确处理 NaN,通常将其视为不相等。如果 A 列本身包含 NaN,则 ne(df['A'].shift()) 可能会产生预料之外的 True,具体行为取决于 NaN 的比较规则。在大多数情况下,这种行为是可接受的,因为它会将 NaN 视为一个值的变化。

通过掌握 shift().cumsum() 结合 groupby().transform() 的技巧,开发者可以高效地处理基于分类列变化的复杂数据转换任务,从而提升数据处理的效率和代码的简洁性。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

769

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

661

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

764

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

659

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1325

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

549

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

579

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

730

2023.08.11

AO3中文版入口地址大全
AO3中文版入口地址大全

本专题整合了AO3中文版入口地址大全,阅读专题下面的的文章了解更多详细内容。

1

2026.01.21

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 10.3万人学习

Django 教程
Django 教程

共28课时 | 3.3万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.2万人学习

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

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