You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas按日期和用户id统计累计已支付订单 低效代码优化求助

场景说明

需要统计每个订单的下单日期为止,对应客户的所有已支付订单数量。

  • 输入数据样例:输入数据样例
  • 预期输出效果:预期输出样例

原有实现代码运行效率极低,10万行数据需要运行10小时以上,原代码如下:

orders_paid,orders_inkasso = []

for y,row in df_dated_filt.iterrows():
    x = x + 1
    orders_paid.append(df_dated_filt[(df_dated_filt["order_id"] != row["order_id"]) & (df_dated_filt["m_order_paid"] == 1) & 
                      (df_dated_filt["customer_id"] == row["customer_id"]) & 
                      (pd.to_datetime(df_dated_filt['order_date'])<pd.to_datetime(row['order_date']))]["order_id"].count())
df_dated_filt["m_orders_paid"] = orders_paid
性能问题根源
  • 使用iterrows做行级遍历,本身性能远低于pandas向量化操作
  • 每次循环都对全表做布尔筛选,时间复杂度为O(n²),数据量越大耗时增长越快
  • 循环内重复执行pd.to_datetime转换日期,产生大量无效计算
优化方案

用pandas分组排序+累计求和的向量化逻辑完全替代循环,时间复杂度降低到O(n log n),适配十万乃至百万级数据量:

import pandas as pd

# 提前统一转换日期格式,仅执行一次
df_dated_filt['order_date'] = pd.to_datetime(df_dated_filt['order_date'])

# 计算每个客户每个日期的已支付订单数
daily_paid = df_dated_filt.groupby(['customer_id', 'order_date'])['m_order_paid'].sum().reset_index(name='daily_cnt')
# 按客户+日期排序
daily_paid = daily_paid.sort_values(['customer_id', 'order_date'])
# 按客户分组,累计求和后向前移一位,空值填0,得到截止到前一天的累计已支付数
daily_paid['m_orders_paid'] = daily_paid.groupby('customer_id')['daily_cnt'].cumsum().shift(fill_value=0)
# 把结果merge回原表
df_dated_filt = df_dated_filt.merge(daily_paid[['customer_id', 'order_date', 'm_orders_paid']], on=['customer_id', 'order_date'], how='left')
效果说明

10万行数据的计算耗时可以控制在100ms以内,性能提升超5个数量级,逻辑和原需求完全对齐,支持同一个客户同一天提交多笔订单的场景。

内容的提问来源于stack exchange,提问作者Ridvan Aydin Sibic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 21:45:04