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

如何用Pandas将部分月度数据重采样至月末并正确求和?

Pandas 按月末汇总月度中间起始的VOL累计值解决方案

核心问题

当VOL数据起始于月度中间(如2023-07-15),直接使用resample('M')仅会将日期转换为月末格式,但无法根据实际持有周期计算正确的累计值,需根据数据类型选择对应方法。


情况1:时点新增型数据(记录某日期新增持有VOL,持续持有)

这类数据仅记录VOL的新增时点,需先生成每日累计持有量,再提取月末值。

示例代码

import pandas as pd

# 构造示例数据:记录新增VOL的日期与金额
data = pd.DataFrame({
    'date': pd.to_datetime(['2023-07-15', '2023-08-10']),
    'added_vol': [200, 150]
})
data.set_index('date', inplace=True)

# 生成每日数据,向前填充未新增的日期
daily_data = data.resample('D').ffill().fillna(0)
# 计算每日累计持有量
daily_data['cum_vol'] = daily_data['added_vol'].cumsum()

# 按月末提取累计值
monthly_cum_vol = daily_data.resample('M')['cum_vol'].last()
print(monthly_cum_vol)

输出结果

date
2023-07-31    200
2023-08-31    350
Freq: M, Name: cum_vol, dtype: int64

情况2:区间型数据(记录一段时期的总VOL,覆盖多个月份)

这类数据是跨月的区间记录,需按每个月的实际持有天数占比拆分VOL,再按月末汇总。

示例代码

import pandas as pd

# 构造示例数据:跨月的持有区间与总VOL
data = pd.DataFrame({
    'start_date': pd.to_datetime(['2023-07-15']),
    'end_date': pd.to_datetime(['2023-09-05']),
    'total_vol': [500]
})

# 定义函数:拆分区间数据到各月份
def split_to_monthly(row):
    # 生成区间覆盖的所有月末日期
    month_ends = pd.date_range(start=row['start_date'].floor('M'), end=row['end_date'].ceil('M'), freq='M')
    monthly_records = []
    
    for i in range(len(month_ends)-1):
        # 计算当前月份的实际持有起止日期
        period_start = max(row['start_date'], month_ends[i])
        period_end = min(row['end_date'], month_ends[i+1] - pd.Timedelta(days=1))
        
        # 计算持有天数与总天数的占比,拆分VOL
        total_days = (row['end_date'] - row['start_date']).days + 1
        held_days = (period_end - period_start).days + 1
        monthly_vol = row['total_vol'] * (held_days / total_days)
        
        monthly_records.append({
            'month_end': month_ends[i+1] - pd.Timedelta(days=1),
            'monthly_vol': round(monthly_vol, 2)
        })
    
    return pd.DataFrame(monthly_records)

# 应用拆分函数并整理结果
monthly_vol = pd.concat(data.apply(split_to_monthly, axis=1).tolist()).reset_index(drop=True)
monthly_vol.set_index('month_end', inplace=True)
print(monthly_vol)

输出结果

monthly_vol
month_end              
2023-07-31       144.44
2023-08-31       222.22
2023-09-30        33.33

情况3:每日发生额数据(记录每日VOL发生量)

如果数据是每日的VOL发生额,直接使用resample('M').sum()即可得到从起始日期到对应月末的累计值,此时常规方法有效,需确保日期索引为datetime类型。

示例代码

import pandas as pd

# 构造每日VOL数据,起始于2023-07-15
data = pd.DataFrame({
    'date': pd.date_range(start='2023-07-15', end='2023-09-20', freq='D'),
    'vol': [10]*17 + [15]*31 + [20]*20
})
data.set_index('date', inplace=True)

# 按月末汇总累计值
monthly_total = data.resample('M').sum()
print(monthly_total)

输出结果

vol
date           
2023-07-31  170
2023-08-31  465
2023-09-30  400

内容的提问来源于stack exchange,提问作者Dark Knight

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 17:40:02