加快Python.loc函数搜索速度
我从表中取出一个值,根据其他列中的匹配项搜索该值。现在,因为有几十万个网格单元需要处理,所以每次调用函数都需要几秒钟,但加起来需要几个小时。有没有更快的方法加快Python.loc函数搜索速度,python,pandas,performance,dataframe,search,Python,Pandas,Performance,Dataframe,Search,我从表中取出一个值,根据其他列中的匹配项搜索该值。现在,因为有几十万个网格单元需要处理,所以每次调用函数都需要几秒钟,但加起来需要几个小时。有没有更快的方法 data_1 = data.loc[(data['test1'] == test1) & (data['test2'] == X) & (data['Column'] == col1) & (data['Row']== row1)].Value 样本数据 Column Row Value test2 te
data_1 = data.loc[(data['test1'] == test1) & (data['test2'] == X) & (data['Column'] == col1) & (data['Row']== row1)].Value
样本<代码>数据
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
您可以通过
test1
、test2
、列
和行
进行索引,然后根据该索引进行查找
索引:
data.set_index(["test1", "test2", "Column", "Row"], inplace=True)
然后执行以下操作进行查找:
data_1 = data.loc[(test1, X, col1, row1)].Value
您可以通过
test1
、test2
、列
和行
进行索引,然后根据该索引进行查找
索引:
data.set_index(["test1", "test2", "Column", "Row"], inplace=True)
然后执行以下操作进行查找:
data_1 = data.loc[(test1, X, col1, row1)].Value
也许有必要快速通读一下,看看什么最适合你的需要 一个选项是使用
.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切片得到了以下结果
(注意,此时我意识到我错过了一次查找,因此可能会影响总时间计数,但比率应为真)
现在,下一部分包含将数据帧转换为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)
%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)
大约30%的改善
转换时间:
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)
%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%的情况更糟您可以快速浏览一下,看看什么最适合您的需要 一个选项是使用
.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切片得到了以下结果
(注意,此时我意识到我错过了一次查找,因此可能会影响总时间计数,但比率应为真)
现在,下一部分包含将数据帧转换为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)
%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)
大约30%的改善
转换时间:
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)
%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%预期输出是什么?看起来像是将值选择为列表/系列,其中所有列都满足某些条件。是。它在匹配所有其他列的同时查找列
value
中的值。请看:预期输出是什么?看起来像是将值选择为列表/序列,其中所有列都满足某些条件。是。它在匹配所有其他列的同时在列value
中查找值。看看这个:对这个答案非常好奇。你知道它会加速多少吗?只是尝试了一下,结果却花了更长的时间。在一个查看9行的测试文件上(查询一个大得多的数据
文件,但查找9个值),需要1分钟5秒,而不是42秒。对此答案非常好奇。你知道它会加速多少吗?只是尝试了一下,结果却花了更长的时间。在一个查看9行的测试文件上(查询一个大得多的数据
文件,但查找9个值),需要1分钟5秒,而我尝试了42秒。我将其转换一次,然后索引,对于arrayGlad的一个测试样本,它从42秒变为33秒,这很有帮助。我仍然会查看我包含的链接或@scottboston评论的答案,看看numba、numexpr/eval或cython是否不是一个更大的改进,无可否认,在前端做了更多的努力,我尝试了这个方法,将它转换一次,然后索引,对于一个数组的测试样本,它从42秒变为33秒,这很有帮助。我仍然会查看我包含的链接或@scottboston评论的答案,看看numba、numexpr/eval或cython是否不是一个更大的改进,无可否认,在前端做了更多的努力