首页 > 解决方案 > Pandas 中寻找 ID 和旧日期的更快循环

问题描述

所以,我有一个代表购买的数据框有 4 列:

  1. 日期(购买日期,格式为 %Y-%m-%d)
  2. customer_ID(字符串列)
  3. 索赔(1-0 栏表示 1-客户投诉购买,0-客户没有投诉)
  4. claim_value (对于索赔 = 1,它表示公司的索赔成本,对于索赔 = 0,它是 NaN)

我需要构建 3 个新列:

  1. past_purchases(特定客户在此购买之前购买了多少次)
  2. past_claims(特定客户在此次购买之前有多少索赔)
  3. Past_claims_value(客户过去的理赔费用是多少)

到目前为止,这一直是我的方法:

past_purchases = []
past_claims = []
past_claims_value = []

for i in range(0, len(df)):
    date = df['date'][i]
    customer_ID = df['customer_ID'][i]
    df_temp = df[(df['date'] < date) & (df['customer_ID'] == customer_ID)]
    past_purchases.append(len(df_temp))
    past_claims.append(df_temp['claim'].sum())
    past_claims_value.append(df['claim_value'].sum())

df['past_purchases'] = pd.DataFrame(past_purchases)
df['past_claims'] = pd.DataFrame(past_claims)
df['past_claims_value'] = pd.DataFrame(past_claims_value)

代码运行良好,但速度太慢。任何人都可以让它更快地工作吗?谢谢!

Ps:重要的是要检查日期是否较旧,如果客户在同一日期购买了 2 件商品,则不应相互计算。

Pss:我愿意将库用于并行处理,例如 multiprocessing、concurrent.futures、joblib 或 dask,但以前从未以类似的方式使用过。

预期结果:

在此处输入图像描述

标签: pythonpandasloopsdataframeparallel-processing

解决方案


如果日期按升序排序,也许您可​​以尝试使用cumsum过度客户

df.sort_values('date', inplace=True)

new_temp_columns = ['claim_s','claim_value_s']
df[['claim_s','claim_value_s']] = df[new_temp_columns].shift()
df['past_claims'] = df.groupby('customer_ID')['claim_s'].transform(pd.Series.cumsum)
df['past_claims_value'] = df.groupby('customer_ID')['claim_value_s'].transform(pd.Series.cumsum)

# set the min value for the groups
dfc = data.groupby(['customer_ID','date'])[['past_claims','past_claims_value']]
data[['past_claims', 'past_claims_value']] = dfc.transform(min)

# Remove temp columns     
data = data.loc[:, ~data.columns.isin(new_temp_columns)]

同样,这仅在 te date 是 srotes 时才有效


推荐阅读