提高在列表中查找项目索引的速度
Increasing the speed of finding an index of an item in list
我正在尝试加快我编写的程序的速度,在导入 cProfile 后,我发现一个函数占用了大量的计算时间。
就是这个,它在列表中找到一个 numpy.ndarray:
def locate(arr, l ):
for i in range(len(l)):
if np.all(l[i] == arr):
return i
return -1
由于列表无法排序等,我看不出有什么方法可以避免扫描整个列表。我已经阅读了一些关于矢量化的文章,我想知道是否可以在这里应用它,或者是否有任何其他方法可以加快速度?
谢谢
有一个名为 index()
的内置 python 函数,您可以在其中插入一个字符串作为值并在列表中找到它的索引来使用它。
所以你在找 np.where
temp_list=np.array(temp_list)
np.where(temp_list==5)
(array([1, 3, 6, 8]),)
您可能无法避免遍历列表,但您可以加快比较速度:
设置示例:
L = list(np.floor(np.outer(*2*(np.linspace(1,10,1000),))))
arr = L[537]
直接方法供参考:
import itertools as it
next(it.chain((i for i, a in enumerate(L) if np.all(arr==a)), (-1,)))
# 537
timeit(lambda: next(it.chain((i for i, a in enumerate(L) if np.all(arr==a)), (-1,))), number=100)
# 0.27100146701559424
方法 1:使用 np.array_equal
(较慢)
next(it.chain((i for i, a in enumerate(L) if np.array_equal(arr, a)), (-1,)))
# 537
timeit(lambda: next(it.chain((i for i, a in enumerate(L) if np.array_equal(arr, a)), (-1,))), number=100)
# 0.2992244770284742
方法 2:使用无效视图(更快)
arr_v = arr.reshape(-1).view(f'V{arr.itemsize*arr.size}')
next(it.chain((i for i, a in enumerate(L) if arr_v==a.reshape(-1).view(f'V{a.itemsize*a.size}')), (-1,)))
# 537
timeit(lambda: next(it.chain((i for i, a in enumerate(L) if arr_v==a.reshape(-1).view(f'V{a.itemsize*a.size}')), (-1,))), number=100)
# 0.11853155982680619
此处接受的答案使用 np.array_equal
,它首先检查形状,然后进行 all(==)
测试。
另一个SO:
Searching an array for a value faster than np.where(ar==value) using fortran and f2py
我正在尝试加快我编写的程序的速度,在导入 cProfile 后,我发现一个函数占用了大量的计算时间。
就是这个,它在列表中找到一个 numpy.ndarray:
def locate(arr, l ):
for i in range(len(l)):
if np.all(l[i] == arr):
return i
return -1
由于列表无法排序等,我看不出有什么方法可以避免扫描整个列表。我已经阅读了一些关于矢量化的文章,我想知道是否可以在这里应用它,或者是否有任何其他方法可以加快速度?
谢谢
有一个名为 index()
的内置 python 函数,您可以在其中插入一个字符串作为值并在列表中找到它的索引来使用它。
所以你在找 np.where
temp_list=np.array(temp_list)
np.where(temp_list==5)
(array([1, 3, 6, 8]),)
您可能无法避免遍历列表,但您可以加快比较速度:
设置示例:
L = list(np.floor(np.outer(*2*(np.linspace(1,10,1000),))))
arr = L[537]
直接方法供参考:
import itertools as it
next(it.chain((i for i, a in enumerate(L) if np.all(arr==a)), (-1,)))
# 537
timeit(lambda: next(it.chain((i for i, a in enumerate(L) if np.all(arr==a)), (-1,))), number=100)
# 0.27100146701559424
方法 1:使用 np.array_equal
(较慢)
next(it.chain((i for i, a in enumerate(L) if np.array_equal(arr, a)), (-1,)))
# 537
timeit(lambda: next(it.chain((i for i, a in enumerate(L) if np.array_equal(arr, a)), (-1,))), number=100)
# 0.2992244770284742
方法 2:使用无效视图(更快)
arr_v = arr.reshape(-1).view(f'V{arr.itemsize*arr.size}')
next(it.chain((i for i, a in enumerate(L) if arr_v==a.reshape(-1).view(f'V{a.itemsize*a.size}')), (-1,)))
# 537
timeit(lambda: next(it.chain((i for i, a in enumerate(L) if arr_v==a.reshape(-1).view(f'V{a.itemsize*a.size}')), (-1,))), number=100)
# 0.11853155982680619
此处接受的答案使用 np.array_equal
,它首先检查形状,然后进行 all(==)
测试。
另一个SO:
Searching an array for a value faster than np.where(ar==value) using fortran and f2py