在不更改日期的情况下在熊猫中重新取样

时间:2016-01-07 19:49:14

标签: python pandas

假设我使用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除外。)

2 个答案:

答案 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将小于上一个日期。