Pandas统计日期区间内各日期出现次数(大数据量优化需求)
Pandas 高效统计日期区间覆盖次数优化方案
核心思路
避免用循环遍历每个日期区间,改用向量化操作或差分计数法,借助Pandas内置高效函数处理,大幅提升大数据量下的计算效率。
方法一:差分计数法(推荐大数据量使用)
这是效率最高的方案,通过标记区间起始/结束的差分变化,再计算累计和得到每日覆盖次数,全程无循环。
步骤与代码
import pandas as pd # 1. 构造示例数据(替换为你的实际DataFrame) df = pd.DataFrame({ 'date_from': ['2019-08-01', '2019-08-04', '2019-08-07'], 'date_to': ['2019-08-05', '2019-08-07', '2019-08-09'] }) # 2. 将日期列转换为datetime类型(必须步骤,否则无法计算) df['date_from'] = pd.to_datetime(df['date_from']) df['date_to'] = pd.to_datetime(df['date_to']) # 3. 生成差分标记:起始日期+1,结束日期的次日-1 start_records = df[['date_from']].assign(count=1).rename(columns={'date_from': 'date'}) end_records = df[['date_to']].assign(count=-1).rename(columns={'date_to': 'date'}) end_records['date'] += pd.Timedelta(days=1) # 因为区间包含date_to,所以次日才开始减计数 # 4. 合并记录并按日期排序 combined = pd.concat([start_records, end_records]).sort_values('date') # 5. 计算累计和,并补全所有连续日期 full_date_range = pd.date_range( start=combined['date'].min(), end=combined['date'].max() - pd.Timedelta(days=1) ) daily_counts = combined.set_index('date').cumsum().reindex(full_date_range).ffill() # 6. 格式化结果 result = daily_counts.reset_index().rename(columns={'index': 'date'}) result['date'] = result['date'].dt.strftime('%Y-%m-%d') print(result)
优势
- 时间复杂度仅为O(n log n)(主要来自排序),百万级数据也能快速处理
- 内存占用低,无需生成所有区间内的日期序列
方法二:explode展开法(中小数据量适用)
代码更简洁直观,适合数据量不大的场景,通过生成每个区间的日期序列后展开统计。
步骤与代码
import pandas as pd # 1. 构造示例数据 df = pd.DataFrame({ 'date_from': ['2019-08-01', '2019-08-04', '2019-08-07'], 'date_to': ['2019-08-05', '2019-08-07', '2019-08-09'] }) # 2. 转换日期类型 df['date_from'] = pd.to_datetime(df['date_from']) df['date_to'] = pd.to_datetime(df['date_to']) # 3. 生成每个区间的日期序列并展开 df['daily_dates'] = df.apply(lambda row: pd.date_range(row['date_from'], row['date_to']), axis=1) expanded_df = df.explode('daily_dates') # 4. 统计每个日期的出现次数 result = expanded_df['daily_dates'].value_counts().sort_index().reset_index() result.columns = ['date', 'count'] result['date'] = result['date'].dt.strftime('%Y-%m-%d') print(result)
注意事项
- 当数据量超过10万行时,
apply生成日期序列会导致内存占用飙升,计算速度显著下降,此时优先选择差分法。
内容的提问来源于stack exchange,提问作者Николай Черкашин
相关产品推荐
相关产品推荐

