
本文将介绍一种利用 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 pd
def 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) 来填充任何剩余的缺失值,确保所有原始数据都被保留。
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_values
print(df)通过使用 Pandas 的 pivot_table、groupby、ffill 和 bfill 函数,我们可以高效地根据条件更新 DataFrame 中的列值,避免了低效的逐行迭代。这种方法可以显著提高处理大型数据集的性能。
以上就是使用 Pandas DataFrame 根据条件迭代更新列值的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号