在我的df中,我有一个这样的多索引:
df.index.names
FrozenList([u'Ticker', u'Date'])
<class 'pandas.core.frame.DataFrame'>
MultiIndex: 189667 entries, (AAPL, 1992-08-31 00:00:00) to (^DJI, 2017-08-31 00:00:00)
在单个索引 df 上,我会做:
from sklearn.model_selection import train_test_split
df_train, df_test = train_test_split(df, test_size=0.2, shuffle=False)
但是,这不适用于多索引,它只是在 80/20 中削减行。
注意:我不想要随机抽样,只是根据日期拆分 80/20。
有什么线索吗?
编辑:
这就是我获取相关数据的方式(除了两个以上的代码):
import pandas as pd
import pandas_datareader.data as web
tickers = ['AAPL', 'AXP']
def get_data(tickers):
''' Dowloads daily O/H/L/C data for all symbols'''
def data(ticker):
return web.DataReader(ticker, 'yahoo')
datas = map(data, tickers)
return pd.concat(datas, keys=tickers, names=['Ticker', 'Date'])
stock_data = get_data(tickers)
这是这样做的一种方法:
首先按 GroupBy ticker(索引级别 0)获取测试组,然后按日期(降序)对每个结果组进行排序,然后使用 select 获取前 20% 的数据
df_test = stock_data.groupby(level=0).apply(
lambda group: group.sort_index(
ascending=False).iloc[:int(len(group) * .2)]
).reset_index(level=0, drop=True)
df_train是 stock_data
中的所有记录而不是df_test,我们可以在多个索引上使用布尔掩码来获得df_train
df_train = stock_data[~stock_data.index.isin(df_test.index)]
或者对df_test使用相同的代码,其中 .2 替换为 ,8,ascending=False
替换为 ascending=True