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

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,提问作者Николай Черкашин

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:27:26