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

如何简洁计算Pandas Series每行向量与下一行的百分比变化?

计算Pandas Series中每行向量与下一行的百分比变化

需求说明

计算Pandas Series中每行的向量与下一行对应位置元素的百分比变化,公式为(当前行元素 - 下一行元素) / 下一行元素,最后一行因无后续行,结果返回None。

示例输入

import pandas as pd    
a = pd.Series([[1,2,3],[4,5,6],[7,8,9]])
a

输出:

0    [1, 2, 3]
1    [4, 5, 6]
2    [7, 8, 9]
dtype: object

期望输出

0                                  [-0.75, -0.6, -0.5]
1    [-0.42857142857142855, -0.375, -0.333333333333...
2                                                 None
dtype: object

现有解法问题

当前使用嵌套列表推导式实现,但写法过于复杂,可读性差:

import pandas as pd
a = pd.Series([[1,2,3],[4,5,6],[7,8,9]])

pd.Series([ [ [ (xx-yy)/yy for xx,yy in zip(x,y)] if y is not None else None] 
       for x,y in zip(a,a.shift(-1))])

简洁实现方案

方案1:结合apply与shift

利用shift(-1)获取下一行数据,通过apply逐行计算,逻辑更直观:

import pandas as pd
a = pd.Series([[1,2,3],[4,5,6],[7,8,9]])

def calc_pct_change(current, next_row):
    if next_row is None:
        return None
    return [(curr - nxt)/nxt for curr, nxt in zip(current, next_row)]

result = pd.Series([calc_pct_change(x, y) for x, y in zip(a, a.shift(-1))])
print(result)

也可简化为lambda表达式,省去函数定义:

result = a.shift(-1).combine(a, lambda nxt, curr: [(c - n)/n for c, n in zip(curr, nxt)] if nxt is not None else None)

方案2:转换为DataFrame处理(更符合Pandas原生逻辑)

Series存储列表并非最优用法,转为DataFrame后可利用向量化运算,效率更高:

import pandas as pd
a = pd.Series([[1,2,3],[4,5,6],[7,8,9]])

# 将Series转换为DataFrame
df = pd.DataFrame(a.tolist())
# 向量化计算百分比变化
pct_change = (df - df.shift(-1)) / df.shift(-1)
# 将每行结果转回列表格式,最后一行填充None
result = pct_change.apply(list, axis=1).fillna(pd.Series([None], index=[len(a)-1]))
print(result)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 22:07:23