加快Python .loc函数搜索

时间:2019-01-07 21:11:24

标签: python pandas performance dataframe search

我正在从表中提取一个值,根据其他列中的匹配项来搜索该值。现在,由于要处理数十万个网格单元,因此该函数的每次调用都需要花费几秒钟的时间,但总计要花费数小时。有更快的方法吗?

data_1 = data.loc[(data['test1'] == test1) & (data['test2'] == X) & (data['Column'] == col1) & (data['Row']== row1)].Value

示例data

Column  Row Value   test2   test1
2       3   5       X       0TO4
2       6   10      Y       100UP
2       10  5.64    Y       10TO14
5       2   9.4     Y       15TO19
9       2   6       X       20TO24
13      11  7.54    X       25TO29
25      2   6.222   X       30TO34

2 个答案:

答案 0 :(得分:1)

您可以按test1test2ColumnRow进行索引,然后按该索引进行查找。

索引:

data.set_index(["test1", "test2", "Column", "Row"], inplace=True)

,然后执行以下操作:

data_1 = data.loc[(test1, X, col1, row1)].Value

答案 1 :(得分:1)

enhancing performance docs上快速阅读一下,以了解最适合您的需求可能是值得的。

一种选择是使用.values并切片来将其降为numpy。在没有看到您的实际数据或用例的情况下,我创建了以下综合数据:

data=pd.DataFrame({'column':[np.random.randint(30) for i in range(100000)],
                'row':[np.random.randint(50) for i in range(100000)],
                'value':[np.random.randint(100)+np.random.rand() for i in range(100000)],
                 'test1':[np.random.choice(['X','Y']) for i in range(100000)],
                'test2':[np.random.choice(['d','e','f','g','h','i']) for i in range(100000)]})

data.head()

    column  row value       test1   test2
0   4       30  88.367151   X       e
1   7       10  92.482926   Y       d
2   1       17  11.151060   Y       i
3   27      10  78.707897   Y       g
4   19      35  95.204207   Y       h

然后使用%timeit使用.loc索引,布尔掩码和numpy切片得到以下结果 (请注意,这时我意识到我错过了一次查询,因此可能会影响总时间计数,但比率应为真)

%timeit data_1 = data.loc[(data['test1'] == 'X') & (data['column'] >=12) & (data['row'] > 22)]['value']
13 ms ± 538 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit data_1 = data[(data['test1'] == 'X') & (data['column'] >=12) & (data['row'] > 22)]['value']
13.1 ms ± 233 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

现在,这下一部分包含一些将数据帧转换为numpy数组的开销。如果您一次转换它,然后对其进行多次查找,则速度会更快。但是,如果没有,那么一次转换/切片可能会花费更长的时间

不考虑转换时间:

d1=data.values

%timeit d1[(d1[:,3]=='X')&(d1[:,0]>=12)&(d1[:,1]>22)][:,2]
8.37 ms ± 161 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

大约改善了30%

具有转换时间:

%timeit d1=data.values;d1[(d1[:,3]=='X')&(d1[:,0]>=12)&(d1[:,1]>22)][:,2]
20.6 ms ± 624 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

大约差50%