如何用向量化方式高效设置Pandas DataFrame的条件值
向量化方式处理用户团队随时间变更的DataFrame填充问题
针对你遇到的需要根据用户团队变更记录批量填充UserTeam列的问题,完全可以用Pandas的向量化操作替代低效的apply循环,下面是具体实现步骤,全程避免逐行迭代:
步骤1:预处理日期数据
首先必须把所有日期字符串转换为Pandas的datetime类型,这样才能进行正确的日期比较:
import pandas as pd import numpy as np # 初始化原始DataFrame data = { "UserName": ["John", "David", "Katie", "Cristin", "Katie", "John", "David", "David", "John", "Steven", "Steven"], "StartEdit": ["12-Jul-2015", "16-Aug-2015", "20-Aug-2015", "2-Sep-2015", "12-Sep-2015", "23-Nov-2015", "2-Jan-2016", "3-Jan-2016", "10-Feb-2016", "13-Mar-2016", "14-Mar-2016"] } df = pd.DataFrame(data) # 转换日期列为datetime类型 df["StartEdit"] = pd.to_datetime(df["StartEdit"], format="%d-%b-%Y") # 固定团队映射和变更记录 owners_teams = {"Katie":"A", "Cristin":"B", "Steven":"C"} changes = [("John", "01-Jan-2016", "A", "C"), ("David", "12-Dec-2015", "B", "C")]
步骤2:初始化UserTeam列
先用固定团队映射填充已知用户的团队,剩下的用户(John、David)会被设为NaN:
df["UserTeam"] = df["UserName"].map(owners_teams)
步骤3:处理团队变更记录
把变更记录转换成DataFrame,同样转换日期类型,然后和原始DataFrame关联,再用向量化条件判断填充NaN:
# 转换变更记录为DataFrame并处理日期 changes_df = pd.DataFrame(changes, columns=["UserName", "ChangeDate", "OldTeam", "NewTeam"]) changes_df["ChangeDate"] = pd.to_datetime(changes_df["ChangeDate"], format="%d-%b-%Y") # 合并原始df和变更记录df,按UserName关联 df = df.merge(changes_df, on="UserName", how="left") # 用np.where进行向量化判断:日期在变更前用旧团队,变更后用新团队 df["UserTeam"] = np.where( df["UserTeam"].isna(), # 只处理未填充的用户 np.where(df["StartEdit"] < df["ChangeDate"], df["OldTeam"], df["NewTeam"]), df["UserTeam"] # 已填充的用户保持不变 ) # 清理临时列 df = df.drop(["ChangeDate", "OldTeam", "NewTeam"], axis=1)
最终结果
运行完上述代码后,你会得到预期的结果:
UserName StartEdit UserTeam 0 John 2015-07-12 A 1 David 2015-08-16 B 2 Katie 2015-08-20 A 3 Cristin 2015-09-02 B 4 Katie 2015-09-12 A 5 John 2015-11-23 A 6 David 2016-01-02 C 7 David 2016-01-03 C 8 John 2016-02-10 C 9 Steven 2016-03-13 C 10 Steven 2016-03-14 C
为什么这是高效的?
- 全程使用Pandas和NumPy的向量化操作,这些操作基于C语言实现,比Python层面的
apply循环快几个数量级,尤其适合处理百万级以上的大数据量。 - 避免了逐行迭代的开销,所有判断都是批量进行的。
内容的提问来源于stack exchange,提问作者pawelty
相关产品推荐
相关产品推荐

