在(n)天列中滚动最小值

时间:2016-12-09 12:10:31

标签: python pandas

虚拟测试数据:

np.random.seed(1)
ts = pd.DataFrame(np.random.rand(1000), index=pd.date_range('1/1/2000', periods=1000))
ts.columns = ['Val']
#ts['Week'] = ts.index.week
ts.loc['2000-01-30':]

    Val
2000-01-30  0.878143
2000-01-31  0.098347
2000-02-01  0.421108
2000-02-02  0.957890
2000-02-03  0.533165
2000-02-04  0.691877
2000-02-05  0.315516
2000-02-06  0.686501
2000-02-07  0.834626

首先我过滤数据:

tsSig = ts[ts.Val>.5]

现在是我正在努力的部分。我可以创建显示下一个(n)mynums天的新列。

mynums = [1,2,3]
for i in mynums:
        tsSig['+'+str(+i)+'Days'] =  ts['Val'].ix[tsSig.index + pd.DateOffset(days=i)].values

这为此输出提供了{n}天的Val输出:

                 Val    Val_D1        +1Days    +2Days     +3Days
2000-01-02  0.720324    0.000114    0.000114    0.302333    0.146756
2000-01-10  0.538817    0.419195    0.419195    0.685220    0.204452

但我真正想要的是这些+ nDays值的滚动最小值:

期望的输出:

                 Val    Val_D1        +1Days    +2Days     +3Days
2000-01-02  0.720324    0.000114    0.000114    0.000114    0.000114
2000-01-10  0.538817    0.419195    0.419195    0.419195    0.204452

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:1)

尝试pd.concat

rng = range(1, 5)
ts.join(pd.concat([ts.Val.rolling(i).min() for i in rng],
        axis=1, keys=['+{}Days'.format(i) for i in rng]))

enter image description here

答案 1 :(得分:1)

Another approach is transposing the dataframe, finding expanding min and transposing again:

import pandas as pd
import numpy as np

np.random.seed(1)
ts = pd.DataFrame(np.random.rand(1000), index=pd.date_range('1/1/2000', periods=1000))
ts.columns = ['Val']
#ts['Week'] = ts.index.week

tsSig = ts[ts.Val>.5]

mynums = [1,2,3]
for i in mynums:
        tsSig.loc[:, '+'+str(+i)+'Days'] =  ts['Val'].ix[tsSig.index + pd.DateOffset(days=i)].values


tsSig = tsSig.T.expanding(0).min().T 


tsSig.head()
Out[103]: 
                 Val    +1Days    +2Days    +3Days
2000-01-02  0.720324  0.000114  0.000114  0.000114
2000-01-10  0.538817  0.419195  0.419195  0.204452
2000-01-12  0.685220  0.204452  0.204452  0.027388
2000-01-14  0.878117  0.027388  0.027388  0.027388
2000-01-16  0.670468  0.417305  0.417305  0.140387

答案 2 :(得分:1)

另一个反转整个框架,以便可以向前滚动。

tsSig2 = ts[::-1].shift().assign(Val=ts.Val[::-1],
                  plus1=lambda x: x.rolling(1).min(),
                  plus2=lambda x: x.rolling(2).min(), 
                  plus3=lambda x: x.rolling(3).min())[::-1].query('Val > .5')

还有一个新解决方案更好但需要预先设置一个小型虚拟框架。

ts_pre = pd.DataFrame(data=[[0]], index=pd.date_range('1/1/2000', periods=3), columns=['Val'])

tsSig2 = ts_pre.append(ts).assign(plus1=lambda x: x.shift(-1).rolling(1).min(),
                  plus2=lambda x: x.shift(-2).rolling(2).min(), 
                  plus3=lambda x: x.shift(-3).rolling(3).min()).query('Val > .5')

还有一种方法可以很快进行良好的测量。

tsSig = ts.assign(plus1=lambda x: x.shift(-1),
                  plus2=lambda x: x.shift(-2), 
                  plus3=lambda x: x.shift(-3)).query('Val > .5')
tsSig[['plus1', 'plus2','plus3']] = tsSig[['plus1', 'plus2','plus3']].cummin(axis=1)