Python 熊猫数据帧的滚动idxmin/max

Python 熊猫数据帧的滚动idxmin/max,python,pandas,dataframe,indexing,rolling-computation,Python,Pandas,Dataframe,Indexing,Rolling Computation,我相信以下功能是熊猫数据帧滚动argmin/max的有效解决方案: import numpy as np def data_frame_rolling_arg_func(df, window_size, func): ws = window_size wm1 = window_size - 1 return (df.rolling(ws).apply(getattr(np, f'arg{func}'))[wm1:].astype(int) + n

我相信以下功能是熊猫数据帧滚动argmin/max的有效解决方案:

import numpy as np

def data_frame_rolling_arg_func(df, window_size, func):
    ws = window_size
    wm1 = window_size - 1
    return (df.rolling(ws).apply(getattr(np, f'arg{func}'))[wm1:].astype(int) +
            np.array([np.arange(len(df) - wm1)]).T).applymap(
                lambda x: df.index[x]).combine_first(df.applymap(lambda x: np.NaN))
它的灵感来自于

说明:

  • 将numpy argmin/max函数应用于滚动窗口
  • 仅保留非
    NaN
  • 将值转换为
    int
  • 将值重新对齐到原始行号
  • 使用
    applymap
    将行号替换为索引值
  • 与原始的
    数据帧
    组合,填充
    NaN
    ,以添加具有预期
    NaN
    值的第一行

在[1]中:索引=映射(chr,range(ord('a'),ord('a')+10))
[2]中:df=pd.DataFrame((10*np.random.randn(10,3)).astype(int),index=index)
In[3]:df
出[3]:
0   1   2
a-4 150
b 0-6 4
c 7 8-18
d 11 12-16
e 6 3-6
f-14-9
g 6-10-7
h 8 11-25
i-2-10-8
j 0 10-7
[4]中:数据\帧\滚动\参数\函数(df,3,'max')
出[4]:
0    1    2
阿楠楠
b楠楠楠楠楠
c c a b
d d b
e-d-d-e
f d e
g e f e
h h g
i h g
j h h j
[5]中:数据\帧\滚动\参数\函数(df,3,'min')
出[5]:
0    1    2
阿楠楠
b楠楠楠楠楠
c a b c
d b c
电子商务
f f e d
g f g f
h f g h
i i g h
j i h
我的问题是:

  • 你能发现错误吗
  • 有更好的解决办法吗?也就是说:更具性能和/或更优雅

对于那里的熊猫维护者来说:如果已经存在的大熊猫库包括滚动idxmax和idxmin,那就太好了。

我在OP评论中提到的
NaN
问题可以通过以下方式解决:

将numpy导入为np
作为pd进口熊猫
def数据帧滚动idx函数(df,窗口大小,函数):
ws=窗口大小
wm1=窗口大小-1
return(df.rolling(ws,min_periods=0).apply(getattr(np,f'arg{func})),
原始=真)[wm1:].astype(int)+
数组([np.arange(len(df)-wm1)]).T).applymap(
lambda x:df.index[x]).combine_first(df.applymap(lambda x:np.NaN))
def main():
索引=地图(颜色、范围(ord('a')、ord('a')+10))
df=pd.DataFrame((10*np.random.randn(10,3)).astype(int),index=index)
df[0][3:6]=np.NaN
打印(df)
打印(数据\帧\滚动\参数\函数(df,3,'min'))
打印(数据\帧\滚动\参数\函数(df,3,'max'))
如果名称=“\uuuuu main\uuuuuuuu”:
main()
结果:

$python demo.py
0   1   2
a 3.07
b 1.0 3 11
c 1.0 15-6
d.2-16
鄂南0 24
f NaN 0 14
G2.04
h-1.0-11 16
i 17.0 0-2
j 3.0-5-8
0    1    2
阿楠楠
b楠楠楠楠楠
c b a c
d
e-d-d
f d e d
格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格格
h f h g
我
j h h j
0    1    2
阿楠楠
b楠楠楠楠楠
c a c b
d d c b
e d c e
f d e
g e e e
h f f h
i i g h
j i h
NaN
值的处理有点微妙。我希望我的滚动
idxmin/max
函数与常规的
DataFrame
rolling
min
/
max
函数配合良好。默认情况下,当窗口输入显示
NaN
值时,这些值将立即生成
NaN
值。默认情况下,滚动
应用
功能也是如此。但是对于apply函数,这是一个问题,因为我无法将
NaN
值转换为索引。然而,这是一个遗憾,因为输出中的
NaN
值显示出来是因为它们可以在输入中找到,所以输入中的
NaN
值索引是我希望滚动
idxmin/max
函数产生的。幸运的是,如果我使用以下参数组合,这正是我将得到的结果:

  • 熊猫
    rolling
    功能的
    min\u periods=0
    。无论在输入窗口中找到多少个
    NaN
    值,
    apply
    函数都有机会生成自己的值
  • raw=True
    用于
    apply
    功能。此参数确保应用函数的输入作为numpy数组而不是系列传递
    np.argmin/max
    然后将返回第一个输入值的索引
    NaN
    值,这正是我们想要的。应该注意的是,如果没有
    raw=True
    ,即在熊猫系列的情况下,
    np.argmin/max
    似乎忽略了
    NaN
    值,这不是我们想要的。
    raw=True
    的好处在于它也应该提高性能!稍后再谈

我上一个答案中的解决方案设法为
NaN
输入值提供适当的索引值,但我意识到这很可能不是本地
idxmin
/
idxmax
默认情况下所做的。默认情况下,它将生成一个
NaN