如何计算每日在途旅程quantity总和并生成对应时间序列DataFrame
问题修复与优化方案
原有代码问题
- 字段名不匹配:你定义的DataFrame中日期字段为
startdate、enddate,筛选条件中错误使用了df['start']、df['end'],会触发字段不存在的报错 - 赋值逻辑错误:循环内直接对
df2['quantities']整列赋值,每次循环都会覆盖整列所有值,最终所有行的结果都会等于最后一次循环的计算值 - 日期类型不统一:原始数据中的日期是字符串格式,直接和datetime类型的时间索引比较存在潜在逻辑问题
最优实现方案(无循环,效率更高)
推荐使用差分累加的方法,时间复杂度仅为O(n),远优于循环方案的O(天数×旅程数),尤其适合数据量较大的场景:
import pandas as pd # 原始数据构造 data = [[10, '2020-03-02', '2020-03-27'], [18, '2020-03-06', '2020-03-10'], [21, '2020-03-20', '2020-05-02'], [33, '2020-01-02', '2020-03-01']] columns = ['quantity', 'startdate', 'enddate'] df = pd.DataFrame(data, columns=columns) # 转换日期字段为datetime类型 df['startdate'] = pd.to_datetime(df['startdate']) df['enddate'] = pd.to_datetime(df['enddate']) # 构造差分事件:旅程开始日加对应quantity,结束日减对应quantity events = pd.concat([ pd.Series(df['quantity'].values, index=df['startdate']), pd.Series(-df['quantity'].values, index=df['enddate']) ]) # 按天聚合事件值,生成完整日期索引 daily_event = events.resample('D').sum() full_date_idx = pd.date_range(start='2020-01-01', end='2020-06-01', freq='D') daily_event = daily_event.reindex(full_date_idx, fill_value=0) # 累加得到每日在途旅程的quantity总和 df2 = daily_event.cumsum().to_frame(name='quantities')
逻辑说明
因为需求是「当日日期大于start date且小于end date才算在途」,刚好符合差分累加的计算逻辑:开始日加的量从次日起生效,结束日减的量从次日起生效,完全匹配计算规则。
原有循环代码修复版
如果要保留循环的实现方式,调整后可正常运行,但仅推荐小数据量场景使用:
# 转换日期字段为datetime类型 df['startdate'] = pd.to_datetime(df['startdate']) df['enddate'] = pd.to_datetime(df['enddate']) index2 = pd.date_range(start='2020-01-01', end='2020-06-01', freq='D') df2 = pd.DataFrame(0, index=index2, columns=['quantities']) for t in index2: mask = (df['startdate'] < t) & (df['enddate'] > t) # 仅给当前日期对应的行赋值 df2.loc[t, 'quantities'] = df.loc[mask, 'quantity'].sum()
内容的提问来源于stack exchange,提问作者ric
相关产品推荐
相关产品推荐

