假设我使用pandas下载每日股票价格数据:
df = web.DataReader('YHOO', 'yahoo', '1/1/2004', '1/31/2004')['Close']
我想要在每周的第一个交易日收盘价。这通常是星期一,但如果星期一是假日,则会是星期二。
所以我尝试重新取样:
df.resample('W-MON', how='last')
得到这个:
Date
2004-01-05 46.900002
2004-01-12 49.740002
2004-01-19 48.110001
2004-01-26 48.160000
2004-02-02 46.980000
Pandas非常巧妙地仅在星期一给我数据。但2004-01-19
是假期,实际上不在df
:
Date
2004-01-02 45.400002
2004-01-05 46.900002
...
2004-01-15 48.090000
2004-01-16 48.110001
2004-01-20 47.660000
2004-01-21 47.380001
...
有没有办法让它从星期一或之后的数据框每周给出第一个日期? (因此,上面的结果,2004-01-19
替换2004-01-20
除外。)
答案 0 :(得分:2)
如果我们选择将错过的日期(例如2004-01-19
> )移至重新采样时间段内的最后一个日期(例如2004-01-16
),那么可以通过应用来完成resampling
不仅是收盘价,还包括Date
本身:
import pandas as pd
import pandas.io.data as pdata
df = pdata.get_data_yahoo('YHOO', start='2004-1-1', end='2004-1-31')
df['Date'] = df.index
df = df[['Close', 'Date']]
result = df.resample('W-MON', how='last')
result = result.set_index('Date')
产量
Close
Date
2004-01-05 46.900002
2004-01-12 49.740002
2004-01-16 48.110001
2004-01-26 48.160000
2004-01-30 46.980000
由于df
有一个Date
列,df.resample('W-MON', how='last')
会在每个重新采样组中找到最后一个价格和最后一个日期。
要解决原始问题,2004-01-19
中缺少的日期会被df
中的下一个日期替换,您可以使用
In [343]: df.index.searchsorted(result.index)
Out[343]: array([ 1, 6, 11, 15, 20])
查找result.index
中的日期将“适合”df.index
的序数索引,以便维护排序顺序。这些索引告诉我们df.index
中的日期{em>在result.index
的相应日期之后上或之后:
In [349]: df.iloc[[1,6,11,15]].index
Out[349]: DatetimeIndex(['2004-01-05', '2004-01-12', '2004-01-20', '2004-01-26'], dtype='datetime64[ns]', name=u'Date', freq=None)
然后使用这些序数索引将df.index
的日期重新分配回result.index
:
import pandas as pd
import pandas.io.data as pdata
df = pdata.get_data_yahoo('YHOO', start='2004-1-1', end='2004-1-31')['Close']
result = df.resample('W-MON', how='last')
idx = df.index.searchsorted(result.index)
# np.clip reduces the index by 1 if a date in result.index comes after all dates in df.index
idx = np.clip(idx, 0, len(df)-1)
result.index = df.iloc[idx].index
产量
Date
2004-01-05 46.900002
2004-01-12 49.740002
2004-01-20 48.110001
2004-01-26 48.160000
2004-01-30 46.980000
Name: Close, dtype: float64
请注意,上次日期将移至2004-01-30
,因为2004-02-02
也不在df.index
中,而df.index
中的最后一个可用日期为2004-01-30
。
答案 1 :(得分:0)
您可以查询任何小于上一日期的星期几:
weekdays = np.array(map(lambda x: x.weekday(), df.index))
df[weekdays < np.roll(weekdays, 1)]
这是有效的,因为weekday
从星期一的0
开始,并从那里开始递增。因此,一周的第一天的weekday
将小于上一个日期。