看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
这个案例将充分利用 pandas 的扩展窗口进行数据逻辑计算,通过这个案例将帮助我们理解 pandas 扩展窗口的计算逻辑。
我们的源数据是一个 Series,如下:
import pandas as pd
import numpy as np
ser = pd.Series([1, 2, 1, 3, 5, 6, 1, 6, 6])
ser
'''
0 1
1 2
2 1
3 3
4 5
5 6
6 1
7 6
8 6
dtype: int64
'''
Series 的值是一个数值,其中有很多值是重复出现的,现在希望得到一个相同形状的列,对应的值为此位置上的值的上一个相同值之间间隔几个值位。
比如,索引 6 的值 1,它上一个值为索引 2 的值,他们之间有 3、5、6 三个值,因此此位置的结果值为 3。
对于之前没有相同值时,结果设置为 None。
由于是当前值在之前所有值的计算逻辑,非常适用使用 expanding()
扩展窗口,因为它的迭代逻辑是当前值及之前所有值组成的 Series,直到所有值迭代完成。
关于重复值间隔值的计算,我们可以写一个函数,让 apply() 来应用。
由于我们要让扩展窗口的 apply() 来调用函数,因此先编写这个函数。这个函数输入的是一个 Series,这个 Series 是当前值及以前所有值组成。
在这个 Series 中查询出当前值的所有值,当前值是 Series 的最后一个值,用 tail(1)
查询后是单个值的 Series,需要用 squeeze()
降维转为标量。
如果查询出来的数据是多个值则继续求间隔数,否则只有一个值返回 None 即可。
求间隔值我们可以利用自然索引的差值(如果索引不是自然索引可以提前进行转换),差值的绝对值减去 1 就得到了两个相同数之间间隔的数据量。
完成的函数如下:
def func(x: pd.Series):
same = x[x == x.tail(1).squeeze()]
if len(same) > 1:
idx = same.tail(2).index
val = abs(idx[0]-idx[1]) - 1
else:
val = np.nan
return val
扩展窗口应用以上函数:
ser.expanding().apply(func)
'''
0 NaN
1 NaN
2 1.0
3 NaN
4 NaN
5 NaN
6 3.0
7 1.0
8 0.0
dtype: float64
'''
这样就得到了最终的结果。
(完)
更新时间:Aug. 18, 2024, 4:01 p.m. 标签:pandas python 间隔