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

如何计算含NaN/0的Pandas Series三值间的pct_change?

问题描述

场景

我有一个包含3个值的Pandas Series,值可能为NaN、0或任意正数,需要尽可能计算该序列的百分比变化(pct_change),无法计算时输出0。

示例输入序列

[0,nan,50]
[0,0,0]
[0,0,50]
[nan,nan,50]
[nan,nan,0]
[0,0,nan]
[0,nan,0]

尝试过的方案

参考相关问题尝试了忽略NaN或位移的方法,但要么得到空值,要么结果不符合预期。理想情况是无法计算时输出0。

测试代码

import pandas as pd

series_test = pd.Series([0, None, 50])
# 仅输出NaN或inf
series_test.pct_change().where(series_test.notna()) 
# 输出空结果
series_test.pct_change(fill_method=None)[series_test.shift(2).notnull()].dropna() 

预期输出

[0,nan,50] - 0 (未定义场景)
[0,0,0] - 0 (未定义场景)
[0,0,50] - 0 (未定义场景)
[nan,nan,50] - 0 (未定义场景)
[nan,nan,0] - 0 (未定义场景)
[0,0,nan] - 0 (未定义场景)
[0,nan,0] - 0 (未定义场景)
[1,nan,5] - 400%
[0,1,5] - 400%
[1,2,nan] - 100%
[1,1.3,1.8] - 80%

解决方案

根据预期输出反推的核心规则:仅当序列中存在至少两个非NaN的正数时,取第一个正数和最后一个正数计算百分比变化;其他所有无法计算的场景返回0。

实现代码如下:

import pandas as pd
import numpy as np

def calculate_pct_change(series):
    # 提取所有非NaN的有效数值
    valid_vals = series.dropna().values
    # 有效数值不足2个,返回0
    if len(valid_vals) < 2:
        return 0
    # 筛选出所有大于0的数值
    positive_vals = valid_vals[valid_vals > 0]
    # 正数不足2个,返回0
    if len(positive_vals) < 2:
        return 0
    # 取第一个和最后一个正数
    first_pos = positive_vals[0]
    last_pos = positive_vals[-1]
    # 计算百分比变化并转成百分比格式
    pct = ((last_pos - first_pos) / first_pos) * 100
    # 格式化输出,整数百分比显示为整数,否则保留一位小数
    return f"{int(pct)}%" if pct.is_integer() else f"{pct:.1f}%"

# 测试所有示例输入
test_cases = [
    ([0, np.nan, 50], "0"),
    ([0, 0, 0], "0"),
    ([0, 0, 50], "0"),
    ([np.nan, np.nan, 50], "0"),
    ([np.nan, np.nan, 0], "0"),
    ([0, 0, np.nan], "0"),
    ([0, np.nan, 0], "0"),
    ([1, np.nan, 5], "400%"),
    ([0, 1, 5], "400%"),
    ([1, 2, np.nan], "100%"),
    ([1, 1.3, 1.8], "80%")
]

for input_list, expected in test_cases:
    series = pd.Series(input_list)
    result = calculate_pct_change(series)
    print(f"{input_list} - {result} {'(符合预期)' if str(result) == expected else '(不符合预期)'}")

代码解释

  1. 提取有效数值:过滤序列中的NaN,得到非空数值列表;
  2. 基础校验:有效数值不足2个时直接返回0;
  3. 筛选正数:从有效数值中筛选大于0的数,避免0作为除数导致计算错误;
  4. 正数校验:正数数量不足2个时返回0;
  5. 计算与格式化:用第一个和最后一个正数计算百分比变化,转成易读的百分比格式,整数百分比显示为整数,非整数保留一位小数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:34:53