如何根据日期将多索引 df 拆分为 80/20 个部分



在我的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

最新更新