I'm trying to speed up a program I've written, and after importing cProfile, I see that one function takes up a massive bit of computation time.
It's this, which finds an numpy.ndarray in a list:
def locate(arr, l ):
for i in range(len(l)):
if np.all(l[i] == arr):
return i
return -1
As the list can't be ordered etc, I can't see any way to avoid scanning the entire list. I have read some pieces on vectorisation, and I wanted to know if that could be applied here, or if there's any other way to speed this up?
Thanks
You probably cannot avoid walking the list but you can speed up the comparison:
Set up example:
L = list(np.floor(np.outer(*2*(np.linspace(1,10,1000),))))
arr = L[537]
Direct method for reference:
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
Approach 1: Use np.array_equal
(slower)
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
Approach 2: Use void view (faster)
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
有一个名为index()
的内置python函数,您可以通过将字符串作为值插入并在列表中查找其索引来使用它。
So are you looking for np.where
temp_list=np.array(temp_list)
np.where(temp_list==5)
(array([1, 3, 6, 8]),)
How to Check if a Matrix is in a List of Matrices Python
Here the accepted answer uses np.array_equal
which first checks shape, then does the all(==)
test.
Another SO: Check if 2d array exists in 3d array in Python?
Searching an array for a value faster than np.where(ar==value) using fortran and f2py
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.