我想滚动应用pandas.rank。 我尝试使用pandas.rolling.apply,但不幸的是,滚动不适用于'rank'。
有办法吗?
df = pd.DataFrame(np.random.randn(10, 3))
def my_rank(x):
return x.rank(pct=True)
df.rolling(3).apply(my_rank)
答案 0 :(得分:1)
代码:
def my_rank(x):
return pd.Series(x).rank(pct=True).iloc[-1]
df.rolling(3).apply(my_rank)
输出:
0 1 2
0 NaN NaN NaN
1 NaN NaN NaN
2 0.666667 0.333333 0.666667
3 1.000000 0.333333 1.000000
4 0.666667 1.000000 0.333333
5 0.333333 0.666667 0.666667
6 1.000000 0.333333 0.666667
7 0.333333 0.333333 1.000000
8 1.000000 0.666667 1.000000
9 0.666667 1.000000 0.666667
说明:
您的代码(很棒的最小重现示例!)引发以下错误:
AttributeError: 'numpy.ndarray' object has no attribute 'rank'
。
这意味着您的x
函数中的my_rank
是作为numpy数组而不是pandas系列传递的。因此,我首先将return x.rank...
更新为return pd.Series(x).rank..
然后出现以下错误:
TypeError: cannot convert the series to <class 'float'>
这是有道理的,因为pd.Series.rank
接受一系列n个数字并返回一系列n个数字(排名)。但是,由于我们不是在序列上一次调用等级,而是在序列的滚动窗口上重复调用等级,因此每次滚动计算只需要一个数字作为输出。因此iloc[-1]