使用 Pandas DataFrame 根据条件迭代更新列值

使用 pandas dataframe 根据条件迭代更新列值

本文将介绍一种利用 Pandas DataFrame 根据条件更新列值的高效方法,核心思想是通过重塑数据、分组操作以及前向和后向填充,避免了低效的逐行迭代。

问题描述

假设我们有一个 DataFrame,记录了针对特定 Issue ID 在不同日期所做的更改。DataFrame 中包含以下列:Issue_Id、Due_Date、status、estimation_hour、changed_date、changed_parameter、old_value 和 new_value。我们的目标是基于这些数据,为每个 Issue ID 在每次更改日期创建一个快照。这意味着我们需要根据 changed_date,将 new_value 应用于对应的 changed_parameter,从而更新 DataFrame 中其他行的值。

解决方案

直接迭代 DataFrame 的行并更新值效率较低,尤其是当数据量很大时。一种更有效的方法是使用 Pandas 的 pivot_table 函数来重塑数据,然后使用 groupby 函数按 Issue_Id 进行分组,最后使用 ffill (forward fill) 和 bfill (backward fill) 函数来更新值。

以下是具体的实现步骤:

定义更新函数:

import pandas as pddef update_values(df):    return df['new_value'].ffill().fillna(df['old_value'].bfill())

这个函数使用 ffill() 将 new_value 列中的缺失值用前面的有效值填充,然后使用 fillna(df[‘old_value’].bfill()) 将剩余的缺失值用 old_value 列的后向填充值填充。这确保了即使某个参数在特定日期没有更改,也能使用最近的值。

重塑数据:

upd_values = (df.pivot_table(index=df.index, columns='changed_parameter',                             values=['old_value', 'new_value'], aggfunc='first')                .groupby(df['Issue_Id']).apply(update_values)                .droplevel('Issue_Id').fillna(df))

pivot_table 函数将 changed_parameter 列转换为新的列,并将 old_value 和 new_value 作为这些列的值。aggfunc=’first’ 确保对于每个 changed_parameter,只保留第一个值。然后,我们使用 groupby(df[‘Issue_Id’]).apply(update_values) 按 Issue_Id 对数据进行分组,并将 update_values 函数应用于每个组。droplevel(‘Issue_Id’) 移除多余的索引层级。最后,使用 fillna(df) 来填充任何剩余的缺失值,确保所有原始数据都被保留。

更新 DataFrame:

df[upd_values.columns] = upd_values

这行代码将更新后的值赋回原始 DataFrame。

完整代码示例

import pandas as pd# 示例数据data = {'Issue_Id': [101, 101, 101, 101, 101, 101, 101, 102, 102, 102, 102, 102],        'Due_Date': ['1/31/2023', '1/31/2023', '1/31/2023', '1/31/2023', '1/31/2023', '1/31/2023', '1/31/2023', '2/28/2023', '2/28/2023', '2/28/2023', '2/28/2023', '2/28/2023'],        'status': ['closed', 'closed', 'closed', 'closed', 'closed', 'closed', 'closed', 'closed', 'closed', 'closed', 'closed', 'closed'],        'estimation_hour': [40, 40, 40, 40, 40, 40, 40, 50, 50, 50, 50, 50],        'changed_date': ['1/10/2023', '1/15/2023', '1/16/2023', '1/16/2023', '1/20/2023', '1/25/2023', '1/30/2023', '1/10/2023', '1/15/2023', '1/20/2023', '1/25/2023', '1/30/2023'],        'changed_parameter': ['status', 'estimation_hour', 'estimation_hour', 'Due_Date', 'status', 'estimation_hour', 'status', 'status', 'estimation_hour', 'status', 'estimation_hour', 'status'],        'old_value': ['Defined', '0', '20', '1/20/2023', 'Accepted', '30', 'InProgress', 'Defined', '0', 'Accepted', '30', 'InProgress'],        'new_value': ['Accepted', '20', '30', '1/31/2023', 'InProgress', '40', 'Closed', 'Accepted', '30', 'InProgress', '50', 'Closed']}df = pd.DataFrame(data)def update_values(df):    return df['new_value'].ffill().fillna(df['old_value'].bfill())upd_values = (df.pivot_table(index=df.index, columns='changed_parameter',                             values=['old_value', 'new_value'], aggfunc='first')                .groupby(df['Issue_Id']).apply(update_values)                .droplevel('Issue_Id').fillna(df))df[upd_values.columns] = upd_valuesprint(df)

注意事项

确保 DataFrame 按照 changed_date 排序,以保证 ffill 和 bfill 的正确性。此方法假设 changed_parameter 列中的值是有限的,并且可以作为列名使用。如果数据量非常大,可以考虑使用更高效的数据结构或分布式计算框架。

总结

通过使用 Pandas 的 pivot_table、groupby、ffill 和 bfill 函数,我们可以高效地根据条件更新 DataFrame 中的列值,避免了低效的逐行迭代。这种方法可以显著提高处理大型数据集的性能。

以上就是使用 Pandas DataFrame 根据条件迭代更新列值的详细内容,更多请关注创想鸟其它相关文章!

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

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月14日 10:31:26
下一篇 2025年12月14日 10:31:31

相关推荐

发表回复

登录后才能评论
关注微信