使用Pandas子集数据框的更快方法

时间:2019-05-06 22:37:54

标签: pandas

完整数据帧为2.4GB。 目前,我正在基于索引创建布尔掩码并选择数据帧的子集。  索引是DateTimeIndex。 获取子集数据帧大约需要10分钟。有更快的方法吗? 请参阅下面的代码以供参考。

        train_data = pd.read_pickle(self.pkl_path + '/' + "train_data.pkl")
        new_train_data = train_data[(train_data.index.date <= self.end_train.date())
                                    & (self.start_train.date() <= train_data.index.date)]

1 个答案:

答案 0 :(得分:1)

让我们先创建一些数据:

import random, string
import pandas as pd
from datetime import datetime, timedelta

today=datetime.now()
idx=pd.date_range(today, today + timedelta(4999), freq='D')
df = pd.DataFrame([{
    'name1': ''.join([random.choice(string.ascii_letters) for i in range(10)]),
    'name2': ''.join([random.choice(string.ascii_letters) for i in range(10)]),
    'val1': random.randint(0, 2**16),
    'val2': random.randint(0, 2**16),
    'val3': random.randint(0, 2**16),
    } for j in range(5000)],
    index=idx
)

,现在使用df.index和日期字符串的比较来检查执行时间:

%timeit df[(df.index>='2019-06-01')&('2019-08-01'>=df.index)]
  

每个循环742 µs±12.1 µs(平均±标准偏差,共运行7次,每个循环1000个)

与显式datetime.date对象之间的比较(即使用df.index.date,比较的日期与上面的相同):

%timeit df[(df.index.date>=(today + timedelta(days=25)).date())&((today + timedelta(days=25)).date()>=df.index.date)]
  

每个循环4.2 ms±82.9 µs(平均±标准偏差,共运行7次,每个循环100个循环)

您似乎正在使用后者,而前者的性能更高。

更新

如果您想更快一点,可以更明确一些,例如,使用以下命令中继到numpy.datetime64数组的比较:

start_date=pd.to_datetime(['2019-06-01 00:00:00']).values[0]
end_date=pd.to_datetime(['2019-08-01 00:00:00']).values[0]

%timeit df[(df.index.values>=start_date)&(df.index.values<=end_date)]
  

每个循环594 µs±13.5 µs(平均±标准偏差,共运行7次,每个循环1000次)