如何在pandas .loc结果中高效应用函数?超400万行数据优化需求
解决方法:用矢量化操作替代apply处理大数据量
你的核心问题是避免逐行处理(apply/at),同时正确给.loc筛选后的行赋值。直接用Series传给函数导致报错,是因为你的get_working_days_delta期望单个日期值,而非整个Series。针对400万行的数据集,矢量化操作是唯一高效的方案——它基于C实现,速度比apply快100~1000倍。
错误原因分析
你原来的代码有两个问题:
- 直接把整个
df["DATE_1"]/df["DATE_2"]传给get_working_days_delta,函数无法处理Series类型输入 - 即使改写成
df.apply(lambda row: cal.get_working_days_delta(row["DATE_1"], row["DATE_2"]), axis=1),apply本质还是逐行循环,400万行的速度会慢到无法接受
最优实现方案
根据你的get_working_days_delta功能,分两种情况给出代码:
情况1:仅计算标准工作日差(无自定义节假日)
直接用numpy的busday_count,它本身就是矢量化的工作日计算函数:
import numpy as np # 定义筛选条件 mask = df["SERIES"] != 0 # 将日期转换为busday_count需要的datetime64[D]格式 date1_arr = df.loc[mask, "DATE_1"].values.astype("datetime64[D]") date2_arr = df.loc[mask, "DATE_2"].values.astype("datetime64[D]") # 计算工作日差并赋值回SERIES列 df.loc[mask, "SERIES"] = np.busday_count(date1_arr, date2_arr)
情况2:包含自定义节假日
如果你的get_working_days_delta需要排除特定节假日,只需把节假日列表转换成datetime64数组,传给busday_count的holidays参数:
import numpy as np # 自定义节假日列表(示例,替换成你的实际节假日) custom_holidays = np.array(["2024-01-01", "2024-02-10", "2024-05-01"], dtype="datetime64[D]") mask = df["SERIES"] != 0 date1_arr = df.loc[mask, "DATE_1"].values.astype("datetime64[D]") date2_arr = df.loc[mask, "DATE_2"].values.astype("datetime64[D]") # 传入节假日参数计算 df.loc[mask, "SERIES"] = np.busday_count(date1_arr, date2_arr, holidays=custom_holidays)
特殊情况:自定义复杂工作日逻辑
如果你的get_working_days_delta有非常特殊的逻辑(比如只计算某几个时段的工作日),可以把函数改造成支持Series输入,用pandas的矢量化方法实现。例如:
def vectorized_get_working_days_delta(date1_series, date2_series, holidays=None): # 这里用矢量化逻辑重写你的原函数 date1_arr = date1_series.values.astype("datetime64[D]") date2_arr = date2_series.values.astype("datetime64[D]") # 加上你的自定义逻辑,比如过滤特定星期几等 return np.busday_count(date1_arr, date2_arr, holidays=holidays, weekmask="1111100") # 示例:排除周末 # 调用并赋值 mask = df["SERIES"] != 0 df.loc[mask, "SERIES"] = vectorized_get_working_days_delta(df.loc[mask, "DATE_1"], df.loc[mask, "DATE_2"])
关键提示
- 矢量化操作是处理百万级数据集的核心,一定要避免逐行循环
- 如果你的原
get_working_days_delta无法修改,优先考虑用numpy/pandas的内置矢量化函数替代,而非强行套用apply
内容的提问来源于stack exchange,提问作者Davi Milhome
相关产品推荐
相关产品推荐

