我正在从表中提取一个值,根据其他列中的匹配项来搜索该值。现在,由于要处理数十万个网格单元,因此该函数的每次调用都需要花费几秒钟的时间,但总计要花费数小时。有更快的方法吗?
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
答案 0 :(得分:1)
您可以按test1
,test2
,Column
和Row
进行索引,然后按该索引进行查找。
索引:
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%