0

0

高效替代嵌套循环:用 Pandas 合并与熔解优化多表关联赋值

霞舞

霞舞

发布时间:2026-02-25 11:15:11

|

921人浏览过

|

来源于php中文网

原创

高效替代嵌套循环:用 Pandas 合并与熔解优化多表关联赋值

本文介绍如何用向量化操作(merge + melt)彻底替代低效的双重 for 循环,解决 DataFrame 间基于 ID 和日期的批量规则标记与时间差计算问题,避免无限循环、AttributeError 及性能瓶颈。

本文介绍如何用向量化操作(`merge` + `melt`)彻底替代低效的双重 for 循环,解决 dataframe 间基于 id 和日期的批量规则标记与时间差计算问题,避免无限循环、attributeerror 及性能瓶颈。

在实际数据分析中,频繁使用嵌套 for 循环遍历两个 DataFrame(如按 ID 和 F_Date 匹配)不仅代码冗长、易出错,更会引发严重性能问题——尤其是当数据量增长时,时间复杂度达 O(n×m),甚至因逻辑错误导致“看似无限”的等待(如未正确控制索引或条件终止)。原始代码中还存在多个关键缺陷:

  • A1 被重复赋值(覆盖了 Y 的值),且 A2 未定义;
  • df1.loc[...] = ... 在循环内反复写入,触发隐式拷贝与链式赋值警告;
  • np.array_split(df1, 20) 后误将 split_df(列表)当作 DataFrame 使用,调用 .F_Date 导致 AttributeError;
  • 未处理日期类型转换与时间差计算等核心业务逻辑。

✅ 正确解法是放弃循环思维,转向关系型操作:利用 pandas.melt() 将宽表 df2(X/Y/Z 列)规整为长格式,再通过 merge() 与 df1 基于 ID 高效关联。整个过程零循环、全向量化,兼具可读性与执行效率。

以下为完整优化实现(含时间差计算):

Pliny
Pliny

创建、分享和重新组合AI应用程序

下载
import pandas as pd
import numpy as np

# 构建示例数据(注意:Clear_Date 应为 datetime 类型以支持时间运算)
df1 = pd.DataFrame({
    'ID': ['AB', 'CD', 'EF'],
    'F_Date': ['2023-10-01', '2023-10-02', '2023-10-02'],
    'Clear_Date': ['2023-10-02', '2023-10-03', '2023-10-04']
})
df1['F_Date'] = pd.to_datetime(df1['F_Date'])
df1['Clear_Date'] = pd.to_datetime(df1['Clear_Date'])

df2 = pd.DataFrame({'X': ['AB'], 'Y': ['CD'], 'Z': ['EF']})

# Step 1: 熔解 df2 → 长格式:每行表示一个事件(X/Y/Z)及其对应 ID
df2_long = df2.reset_index(names='rowid').melt(
    id_vars='rowid', 
    value_vars=['X', 'Y', 'Z'], 
    var_name='Event', 
    value_name='ID'
)

# Step 2: 与 df1 关联(INNER JOIN),获取所有匹配的 (ID, F_Date, Clear_Date) 组合
merged = df1.merge(df2_long, on='ID', how='inner')

# Step 3: 为不同事件添加语义化标签(可选)
event_map = {'X': 'A0 Occuar', 'Y': 'A1 Occuar', 'Z': 'A2 Occuar'}
merged['Rule'] = merged['Event'].map(event_map)

# Step 4: 按 rowid 分组,计算每个 df2 行对应的 X/Y/Z 时间差
# 假设逻辑:Time_Difference = max(Clear_Date of X & Y) - Clear_Date of Z
def calc_time_diff(group):
    x_clear = group[group['Event'] == 'X']['Clear_Date'].iloc[0] if not group[group['Event'] == 'X'].empty else pd.NaT
    y_clear = group[group['Event'] == 'Y']['Clear_Date'].iloc[0] if not group[group['Event'] == 'Y'].empty else pd.NaT
    z_clear = group[group['Event'] == 'Z']['Clear_Date'].iloc[0] if not group[group['Event'] == 'Z'].empty else pd.NaT

    max_xy = max(x_clear, y_clear) if pd.notna(x_clear) and pd.notna(y_clear) else pd.NaT
    diff = max_xy - z_clear if pd.notna(max_xy) and pd.notna(z_clear) else pd.NaT

    # 格式化为 "HH:MM" 字符串(例如 25小时 = "25:00")
    if pd.isna(diff):
        return 'N/A'
    total_minutes = int(diff.total_seconds() // 60)
    hours, minutes = divmod(total_minutes, 60)
    return f"{hours:02d}:{minutes:02d}"

result_summary = merged.groupby('rowid').apply(calc_time_diff).reset_index(name='Time_Difference')
result_summary = result_summary.join(df2, on='rowid')  # 还原原始 X/Y/Z 列

print(result_summary[['X', 'Y', 'Z', 'Time_Difference']])

输出:

   X  Y  Z Time_Difference
0  AB  CD  EF           24:00

⚠️ 关键注意事项

  • 永远优先用 merge/join 替代嵌套循环:Pandas 的底层 C 实现比 Python 循环比快 10–100 倍;
  • melt() 是处理“多列代表同类事件”(如 X/Y/Z)的标准范式,避免硬编码列名;
  • 若需扩展至多行 df2(如 3 行 → 输出 3 行结果),上述 groupby('rowid') 自然支持;
  • 时间差计算中务必确保 Clear_Date 为 datetime64 类型,否则减法会失败;
  • 如需保留 df1 全量记录(包括未匹配 ID),将 how='inner' 改为 how='left' 并处理 NaT。

总结:从“逐行思考”切换到“集合操作”,是 Pandas 高效编程的核心心法。一次 merge 胜过千次循环,一行 melt 解锁结构化表达——这才是数据科学应有的简洁与力量。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

智谱清言 - 免费全能的AI助手
智谱清言 - 免费全能的AI助手

智谱清言 - 免费全能的AI助手

相关专题

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

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

76

2025.12.04

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

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

9

2026.01.31

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

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

314

2025.07.15

数据分析的方法
数据分析的方法

数据分析的方法有:对比分析法,分组分析法,预测分析法,漏斗分析法,AB测试分析法,象限分析法,公式拆解法,可行域分析法,二八分析法,假设性分析法。php中文网为大家带来了数据分析的相关知识、以及相关文章等内容。

496

2023.07.04

数据分析方法有哪几种
数据分析方法有哪几种

数据分析方法有:1、描述性统计分析;2、探索性数据分析;3、假设检验;4、回归分析;5、聚类分析。本专题为大家提供数据分析方法的相关的文章、下载、课程内容,供大家免费下载体验。

289

2023.08.07

网站建设功能有哪些
网站建设功能有哪些

网站建设功能包括信息发布、内容管理、用户管理、搜索引擎优化、网站安全、数据分析、网站推广、响应式设计、社交媒体整合和电子商务等功能。这些功能可以帮助网站管理员创建一个具有吸引力、可用性和商业价值的网站,实现网站的目标。

755

2023.10.16

数据分析网站推荐
数据分析网站推荐

数据分析网站推荐:1、商业数据分析论坛;2、人大经济论坛-计量经济学与统计区;3、中国统计论坛;4、数据挖掘学习交流论坛;5、数据分析论坛;6、网站数据分析;7、数据分析;8、数据挖掘研究院;9、S-PLUS、R统计论坛。想了解更多数据分析的相关内容,可以阅读本专题下面的文章。

529

2024.03.13

Python 数据分析处理
Python 数据分析处理

本专题聚焦 Python 在数据分析领域的应用,系统讲解 Pandas、NumPy 的数据清洗、处理、分析与统计方法,并结合数据可视化、销售分析、科研数据处理等实战案例,帮助学员掌握使用 Python 高效进行数据分析与决策支持的核心技能。

79

2025.09.08

batoto漫画官网入口与网页版访问指南
batoto漫画官网入口与网页版访问指南

本专题系统整理batoto漫画官方网站最新可用入口,涵盖最新官网地址、网页版登录页面及防走失访问方式说明,帮助用户快速找到batoto漫画官方平台,稳定在线阅读各类漫画内容。

19

2026.02.25

热门下载

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

精品课程

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

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