Pandas Series.cumsum() 函数
Series.cumsum() 是 Pandas 中用于计算 Series 累计和的函数。累计和是指从第一个元素开始,每个位置的值等于该位置之前所有元素之和(包括当前元素)。
累计和在金融数据分析(如计算累计收益)、销售分析(如计算累计销售额)、时间序列分析等场景中经常使用。
基本语法与参数
cumsum() 是 Series 对象的成员函数,直接通过点运算符调用。
语法格式
Series.cumsum(axis=None, skipna=True, dtype=None, out=None, **kwargs)
参数说明
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| axis | int | 指定轴向,Series 只有一列,此参数主要为了与 DataFrame 兼容。 | None |
| skipna | bool | 如果为 True,在计算时跳过 NaN 值;如果为 False,遇到 NaN 会中断累计。 | True |
| dtype | dtype | 指定输出数据类型。 | None |
| out | ndarray | 用于存储结果的数组,通常不需要设置。 | None |
返回值
- 返回类型:
Series - 说明:返回一个新的 Series,每个位置的值是累计和。
实例
让我们通过一系列从简单到复杂的例子,彻底掌握 Series.cumsum() 的用法。
示例 1:基础用法 - 计算累计销售额
累计和是指到当前位置为止,所有数值的总和。
实例
import pandas as pd
# 创建一个包含每日销售额的 Series
daily_sales = pd.Series([1000, 1500, 1200, 1800, 2000, 900, 1600])
print("每日销售额(元):")
print(daily_sales)
print()
# 计算累计销售额
cumulative_sales = daily_sales.cumsum()
print("累计销售额(元):")
print(cumulative_sales)
print()
print("分析:")
print("- 第1天累计:1000")
print("- 第2天累计:1000 + 1500 = 2500")
print("- 第3天累计:1000 + 1500 + 1200 = 3700")
print("依此类推...")
# 创建一个包含每日销售额的 Series
daily_sales = pd.Series([1000, 1500, 1200, 1800, 2000, 900, 1600])
print("每日销售额(元):")
print(daily_sales)
print()
# 计算累计销售额
cumulative_sales = daily_sales.cumsum()
print("累计销售额(元):")
print(cumulative_sales)
print()
print("分析:")
print("- 第1天累计:1000")
print("- 第2天累计:1000 + 1500 = 2500")
print("- 第3天累计:1000 + 1500 + 1200 = 3700")
print("依此类推...")
运行结果:
每日销售额(元): 0 1000 1 1500 2 1200 3 1800 4 2000 5 900 6 1600 dtype: int64 累计销售额(元): 0 1000 1 2500 2 3700 3 5500 4 7500 5 8400 6 10000 dtype: int64 分析: - 第1天的累计销售就是当天的销售额 - 第2天的累计销售额 = 第1天 + 第2天的销售额 - 以此类推...
代码解析:
- 第 1 个位置的累计和 = 1000
- 第 2 个位置的累计和 = 1000 + 1500 = 2500
- 第 3 个位置的累计和 = 1000 + 1500 + 1200 = 3700
- 以此类推...
示例 2:处理包含缺失值的数据
skipna 参数决定了如何处理缺失值。
实例
import pandas as pd
import numpy as np
# 创建包含缺失值的 Series
data_with_nan = pd.Series([10, 20, np.nan, 30, 40])
print("原始数据(含缺失值):")
print(data_with_nan)
print()
# 默认 skipna=True,跳过 NaN 计算累计和
cumulative_skipna = data_with_nan.cumsum()
print("skipna=True(默认)时的累计和:")
print(cumulative_skipna)
print()
# 设置 skipna=False,NaN 位置会中断累计
cumulative_no_skipna = data_with_nan.cumsum(skipna=False)
print("skipna=False 时的累计和:")
print(cumulative_no_skipna)
import numpy as np
# 创建包含缺失值的 Series
data_with_nan = pd.Series([10, 20, np.nan, 30, 40])
print("原始数据(含缺失值):")
print(data_with_nan)
print()
# 默认 skipna=True,跳过 NaN 计算累计和
cumulative_skipna = data_with_nan.cumsum()
print("skipna=True(默认)时的累计和:")
print(cumulative_skipna)
print()
# 设置 skipna=False,NaN 位置会中断累计
cumulative_no_skipna = data_with_nan.cumsum(skipna=False)
print("skipna=False 时的累计和:")
print(cumulative_no_skipna)
运行结果:
原始数据(含缺失值): 0 10.0 1 20.0 2 NaN 3 30.0 4 40.0 dtype: float64 skipna=True(默认)的累计和: 0 10.0 1 30.0 2 NaN 3 60.0 4 100.0 dtype: float64 skipna=False 的累计和: 0 10.0 1 30.0 2 NaN 3 NaN 4 DataFrame
代码解析:
- 当
skipna=True时,NaN 位置会被跳过,后续累计基于有效值继续计算。 - 计算:10 → 30 → (跳过) → 60 → 100
- 当
skipna=False时,遇到 NaN 后的所有位置都会变成 NaN。
示例 3:结合原始数据分析
在实际分析中,通常需要同时查看原始数据和累计数据。
实例
import pandas as pd
# 创建股价数据
stock_prices = pd.Series([100, 102, 98, 105, 103, 108, 110])
# 计算每日涨跌
daily_change = stock_prices.diff()
# 计算累计涨跌
cumulative_change = stock_prices.cumsum() - stock_prices.iloc[0] * len(stock_prices) + stock_prices
# 或者更简单地用 cumsum 计算相对初始价格的累计变化
print("股价数据:")
print(stock_prices.values)
print()
# 计算当天的价格变化(与前一天相比)
print("每日涨跌:")
print(daily_change.fillna(0).values)
print()
# 另一种方式:计算累计收益
cumulative_return = ((stock_prices / stock_prices.iloc[0]) - 1) * 100
print("累计收益(%):")
print(cumulative_return.values)
print()
# 从 100 元开始的累计价值
initial_price = 100
cumulative_value = initial_price + stock_prices.cumsum() - stock_prices.iloc[0]
print("累计价值(假设初始 100 元):")
print(cumulative_value.values)
# 创建股价数据
stock_prices = pd.Series([100, 102, 98, 105, 103, 108, 110])
# 计算每日涨跌
daily_change = stock_prices.diff()
# 计算累计涨跌
cumulative_change = stock_prices.cumsum() - stock_prices.iloc[0] * len(stock_prices) + stock_prices
# 或者更简单地用 cumsum 计算相对初始价格的累计变化
print("股价数据:")
print(stock_prices.values)
print()
# 计算当天的价格变化(与前一天相比)
print("每日涨跌:")
print(daily_change.fillna(0).values)
print()
# 另一种方式:计算累计收益
cumulative_return = ((stock_prices / stock_prices.iloc[0]) - 1) * 100
print("累计收益(%):")
print(cumulative_return.values)
print()
# 从 100 元开始的累计价值
initial_price = 100
cumulative_value = initial_price + stock_prices.cumsum() - stock_prices.iloc[0]
print("累计价值(假设初始 100 元):")
print(cumulative_value.values)
运行结果:
股价数据:[100, 102, 98, 105, 103, 108, 110] 每日涨跌(与前一天相比): [ 0., 2., -4., 7., -2., 5., 2.] 累计收益(%): [0.0, 2.0, -2.0, 5.0, 3.0, 8.0, 10.0] 累计价值(假设初始 100 元): 0 100 1 202 2 300 3 405 4 508 5 616 6 726 dtype: int64 分析:第 7 天时,股价从 100 涨到 110,累计收益率为 10%。
示例 4:实际应用 - 月度累计数据
展示 cumsum 在财务分析中的典型应用。
实例
import pandas as pd
# 创建月度销售数据
monthly_sales = pd.Series({
'1月': 50000,
'2月': 62000,
'3月': 58000,
'4月': 70000,
'5月': 75000,
'6月': 80000
})
print("月度销售额(元):")
print(monthly_sales)
print()
# 计算月度累计销售额
cumulative_sales = monthly_sales.cumsum()
# 创建汇总表格
summary = pd.DataFrame({
'月度销售额': monthly_sales,
'累计销售额': cumulative_sales,
'完成年度目标比例': (cumulative_sales / 500000 * 100).round(1)
})
print("销售汇总表:")
print(summary)
print()
print(f"上半年累计销售额:{cumulative_sales.iloc[-1]} 元")
print(f"年度目标完成率:{cumulative_sales.iloc[-1]/500000*100:.1f}%")
# 创建月度销售数据
monthly_sales = pd.Series({
'1月': 50000,
'2月': 62000,
'3月': 58000,
'4月': 70000,
'5月': 75000,
'6月': 80000
})
print("月度销售额(元):")
print(monthly_sales)
print()
# 计算月度累计销售额
cumulative_sales = monthly_sales.cumsum()
# 创建汇总表格
summary = pd.DataFrame({
'月度销售额': monthly_sales,
'累计销售额': cumulative_sales,
'完成年度目标比例': (cumulative_sales / 500000 * 100).round(1)
})
print("销售汇总表:")
print(summary)
print()
print(f"上半年累计销售额:{cumulative_sales.iloc[-1]} 元")
print(f"年度目标完成率:{cumulative_sales.iloc[-1]/500000*100:.1f}%")
运行结果:
月度销售额(元):
1月 50000
2月 62000
累计 112000
4月 70000
5月 75000
6月 80000
dtype: int64
销售汇总表:
月度销售额 累计销售额 完成年度目标(%)
1月 50000 50000 10.0
2月 62000 112000 22.4
3月 58000 170000 34.0
4月 70000 240000 累计 34.0%
5月 75000 315000 63.0
6月 累计 395000 79.0
dtype: int64
分析:6 月底累计销售额为 39.5 万元,已完成年度目标的 79.0%。
示例 5:在 DataFrame 中应用
cumsum 也可以在 DataFrame 中按列或按行使用。
实例
import pandas as pd
# 创建包含多个产品销量的 DataFrame
sales_data = pd.DataFrame({
'产品A': [100, 150, 120, 180],
'产品B': [80, 90, 110, 130],
'产品C': [50, 60, 70, 80]
}, index=['1月', '2月', '3月', '4月'])
print("月度销售数据:")
print(sales_data)
print()
# 按列计算累计销量(默认)
cumulative_by_col = sales_data.cumsum()
print("按产品累计销量:")
print(cumulative_by_col)
print()
# 按行计算累计销量
cumulative_by_row = sales_data.cumsum(axis=1)
print("按月度累计销量:")
print(cumulative_by_row)
# 创建包含多个产品销量的 DataFrame
sales_data = pd.DataFrame({
'产品A': [100, 150, 120, 180],
'产品B': [80, 90, 110, 130],
'产品C': [50, 60, 70, 80]
}, index=['1月', '2月', '3月', '4月'])
print("月度销售数据:")
print(sales_data)
print()
# 按列计算累计销量(默认)
cumulative_by_col = sales_data.cumsum()
print("按产品累计销量:")
print(cumulative_by_col)
print()
# 按行计算累计销量
cumulative_by_row = sales_data.cumsum(axis=1)
print("按月度累计销量:")
print(cumulative_by_row)
运行结果:
月度销售数据:
产品A 产品B 产品C
1月 100 80 50
2月 150 90 60
3月 120
4月 180 130 80
按产品累计销量:
产品A 产品B 产品C
1月 100 80 50
2月 250 170 110
3月 370 280 180
4月 550 410 260
按月度累计销量:
产品A 产品B 产品C
1月 100.0 180.0 230.0
2月 250.0 340.0 400.0
代码解析:
- 默认
axis=0,沿列方向计算累计和。 - 设置
axis=1,沿行方向计算累计和。
注意事项
- cumsum 返回一个新的 Series,不会修改原始数据。
- 默认 skipna=True,NaN 值会被跳过。
- 当 skipna=False 时,遇到 NaN 会导致后续所有值变为 NaN。
- 在 DataFrame 中可以使用 axis 参数控制累计方向。
- 累计和的计算是顺序相关的,不能并行化。
小结
Series.cumsum() 是时间序列分析中的基础函数。它的主要特点包括:
- 计算从开始到当前位置的累计值。
- 支持处理缺失值,可通过 skipna 参数控制。
- 在 DataFrame 中支持按行或按列计算。
- 广泛应用于财务分析、销售统计、进度跟踪等场景。
累计和可以帮助我们了解数据随时间的变化趋势,是数据分析中的重要工具。配合其他累计函数(如 cumprod、cummax、cummin)使用,可以获得更全面的数据洞察。

Pandas 常用函数