从每日股票价格数据中,我想抽样并选择月末价格。我正在使用以下代码完成。
import datetime
from pandas_datareader import data as pdr
import pandas as pd
end = datetime.date.today()
begin=end-pd.DateOffset(365*2)
st=begin.strftime('%Y-%m-%d')
ed=end.strftime('%Y-%m-%d')
data = pdr.get_data_yahoo("AAPL",st,ed)
mon_data=pd.DataFrame(data['Adj Close'].resample('M').apply(lambda x: x[-2])).set_index(data.index)
上面的行选择月末数据,这是输出。
如果我想选择月份的倒数第二个值,我可以使用以下代码来完成。
mon_data=pd.DataFrame(data['Adj Close'].resample('M').apply(lambda x: x[-2]))
这是输出。
然而,索引显示月末值。当我选择当月的倒数第二个值时,我希望指数为2015-12-30而不是2015-12-31。 请建议前进的方向。我希望我的问题很明确。
在期待中感谢你。
此致 阿布舍克巴克
答案 0 :(得分:2)
我不确定是否有办法重新采样。但是,你可以使用groupby和TimeGrouper获得你想要的东西。
import datetime
from pandas_datareader import data as pdr
import pandas as pd
end = datetime.date.today()
begin = end - pd.DateOffset(365*2)
st = begin.strftime('%Y-%m-%d')
ed = end.strftime('%Y-%m-%d')
data = pdr.get_data_yahoo("AAPL",st,ed)
data['Date'] = data.index
mon_data = (
data[['Date', 'Adj Close']]
.groupby(pd.TimeGrouper(freq='M')).nth(-2)
.set_index('Date')
)
答案 1 :(得分:0)
最简单的解决方案是获取新创建的数据帧的索引并减去要返回的天数:
n = 1
mon_data=pd.DataFrame(data['Adj Close'].resample('M').apply(lambda x: x[-1-n]))
mon_data.index = mon_data.index - datetime.timedelta(days=n)
另外,看到你的数据,我认为你应该重新采样不是'月末频率'而是'商业月结束频率':
.resample('BM')
但即使这样也不会涵盖所有内容,因为例如2017年12月29日是商业月末,但此日期不会出现在您的数据中(截至2017年12月8日)。所以你可以添加一个小修复(假设原始数据按日期排序):
end_of_months = mon_data.index.tolist()
end_of_months[-1] = data.index[-1]
mon_data.index = end_of_months
所以,完整的代码将如下所示:
n = 1
mon_data=pd.DataFrame(data['Adj Close'].resample('BM').apply(lambda x: x[-1-n]))
end_of_months = mon_data.index.tolist()
end_of_months[-1] = data.index[-1]
mon_data.index = end_of_months
mon_data.index = mon_data.index - datetime.timedelta(days=n)
顺便说一句:您的.set_index(data.index)
因为data
和mon_data
处于不同的维度而导致错误(mon_data
是按月分组的)