我经常需要通过df
过滤pandas dataframe df[df['col_name']=='string_value']
,我想加快行选择操作,有没有快速的方法呢?
例如,
In [1]: df = mul_df(3000,2000,3).reset_index()
In [2]: timeit df[df['STK_ID']=='A0003']
1 loops, best of 3: 1.52 s per loop
1.52可以缩短吗?
注意:
mul_df()
是创建多级数据框的函数:
>>> mul_df(4,2,3)
COL000 COL001 COL002
STK_ID RPT_Date
A0000 B000 0.6399 0.0062 1.0022
B001 -0.2881 -2.0604 1.2481
A0001 B000 0.7070 -0.9539 -0.5268
B001 0.8860 -0.5367 -2.4492
A0002 B000 -2.4738 0.9529 -0.9789
B001 0.1392 -1.0931 -0.2077
A0003 B000 -1.1377 0.5455 -0.2290
B001 1.0083 0.2746 -0.3934
以下是mul_df()的代码:
import itertools
import numpy as np
import pandas as pd
def mul_df(level1_rownum, level2_rownum, col_num, data_ty='float32'):
''' create multilevel dataframe, for example: mul_df(4,2,6)'''
index_name = ['STK_ID','RPT_Date']
col_name = ['COL'+str(x).zfill(3) for x in range(col_num)]
first_level_dt = [['A'+str(x).zfill(4)]*level2_rownum for x in range(level1_rownum)]
first_level_dt = list(itertools.chain(*first_level_dt)) #flatten the list
second_level_dt = ['B'+str(x).zfill(3) for x in range(level2_rownum)]*level1_rownum
dt = pd.DataFrame(np.random.randn(level1_rownum*level2_rownum, col_num), columns=col_name, dtype = data_ty)
dt[index_name[0]] = first_level_dt
dt[index_name[1]] = second_level_dt
rst = dt.set_index(index_name, drop=True, inplace=False)
return rst
答案 0 :(得分:12)
我一直想将二进制搜索索引添加到DataFrame对象。您可以采用DIY方法按列进行排序并自行完成:
In [11]: df = df.sort('STK_ID') # skip this if you're sure it's sorted
In [12]: df['STK_ID'].searchsorted('A0003', 'left')
Out[12]: 6000
In [13]: df['STK_ID'].searchsorted('A0003', 'right')
Out[13]: 8000
In [14]: timeit df[6000:8000]
10000 loops, best of 3: 134 µs per loop
这很快,因为它总是检索视图而不复制任何数据。
答案 1 :(得分:4)
有些令人惊讶的是,使用.values
数组而不是Series
对我来说要快得多:
>>> time df = mul_df(3000, 2000, 3).reset_index()
CPU times: user 5.96 s, sys: 0.81 s, total: 6.78 s
Wall time: 6.78 s
>>> timeit df[df["STK_ID"] == "A0003"]
1 loops, best of 3: 841 ms per loop
>>> timeit df[df["STK_ID"].values == "A0003"]
1 loops, best of 3: 210 ms per loop
答案 2 :(得分:3)
取决于您之后要对选择做什么,如果您必须进行多种此类选择,groupby
功能也可以使事情变得更快(至少在示例中)。
即使您只需为一个string_value选择行,它也会快一点(但不多):
In [11]: %timeit df[df['STK_ID']=='A0003']
1 loops, best of 3: 626 ms per loop
In [12]: %timeit df.groupby("STK_ID").get_group("A0003")
1 loops, best of 3: 459 ms per loop
但是对GroupBy对象的后续调用将非常快(例如,选择其他sting_values的行):
In [25]: grouped = df.groupby("STK_ID")
In [26]: %timeit grouped.get_group("A0003")
1 loops, best of 3: 333 us per loop