我有一个pandas TimeSeries,并希望将argmax函数应用于滚动窗口。但是,由于从rolling_apply转换为float,如果我应用numpy.argmax()
,我只获取ndarray切片的索引。有没有办法将滚动argmax应用于Series / DataFrame?
Series.idxmax()
或Series.argmax()
都返回一个TimeStamp对象,但是
pandas.rolling_apply(Series, window=10,func=lambda x: pandas.Series(x).idxmax())
只会返回float64。
编辑: 这是一个例子:
import pandas as pd
import numpy as np
import pandas.io.data as web
import datetime
start = datetime.datetime(2001,1,1)
end = datetime.datetime.today()
close = web.DataReader('AAPL','yahoo',start,end).Close
close = close / close.shift(1) - 1
close.resample('W-MON').idxmax() # Timestamp object
close.resample('W-MON').argmax() # Timestamp object
pd.rolling_apply(close.resample('W-MON'), window=52, func=lambda x: pd.Series(x).argmax())
一种工作方式
ix = pd.rolling_apply(close, window=52, func=np.argmax)
ix = np.where(np.isnan(ix),0,ix)
ix = ix.astype(int)
new_index = close.index[52:].map(lambda x: close.index[np.argwhere(close.index==x)-52:np.argwhere(close.index==x)] [ix[np.argwhere(close.index==x)]])
pd.Series(new_index,index=close.index[52:]).apply(lambda x: x.flatten()[0])
但也许有一些" pandonic"方式是什么?
答案 0 :(得分:2)
这不是ATM实现的,但并不困难,请参阅问题here
这是一个解决方法,基本上是“手动”应用,实际上应该非常有效。
In [59]: rc = close.resample('W-MON')
In [60]: def f(rc, i, l):
s = rc.iloc[(i*l):((i+1)*l)]
try:
return s.loc[[s.idxmax()]]
except:
return None
....:
In [61]: pd.concat([ f(rc, i, 52) for i in range(len(rc)) ])
Out[61]:
Date
2001-06-25 0.034350
2002-02-04 0.017548
2003-05-05 0.031083
2004-10-18 0.044588
2005-05-23 0.022959
...
2011-08-29 0.018310
2012-03-19 0.017339
2013-09-23 0.017571
2014-04-28 0.023196
2015-02-16 0.015051
Name: Close, dtype: float64
答案 1 :(得分:1)
仅当您使用 Numpy Extensions 库时,滚动 Pandas 数据帧的 argmax 非常简单。例如,可以像这样获得窗口大小为 3 的整数数据帧列的滚动 argmax:
socket.disconnect()
这将产生一个示例输出:
import pandas as pd
import numpy as np
from numpy_ext import rolling_apply
def get_argmax (mx):
return np.argmax(mx)
df = pd.DataFrame(np.random.randint(0,100,size=(10, 1)), columns=list('A'))
window = 3
df['argmax_rolling3'] = rolling_apply(get_argmax, window, df.A.values)