使用fortran和f2py在数组中搜索比np.where(ar == value)更快的值 [英] Searching an array for a value faster than np.where(ar==value) using fortran and f2py
问题描述
我试图使用np.where在numpy数组(数百个相同)上定位值的索引.它的速度不是那么慢,而是一个瓶颈,所以我开始尝试使用fortran和f2py并编写了这个简单的例程.
I was trying to locate the index of a value on a numpy array (same for hundreds of them) using np.where. Its not that slow but its a bottleneck so i began experimenting with fortran and f2py and wrote this simple routine.
subroutine find_index(array1, num_elements, target_value, loc)
real, intent(in) :: array1(:)
integer, intent(in) :: num_elements, target_value
integer, intent(out) :: loc
do i = 1, num_elements
if (array1(i) .eq. target_value) then
loc = i
exit
endif
end do
end subroutine
但是仍然没有任何改善(与np.where相同).所以我猜想它的方法.对改进代码(python或fortran)有任何建议吗?
But still no improvement (same as np.where). So i guess its about the method. any sugestions on improving the code (python or fortran)?
编辑 我要搜索的值是整数数组中的整数
EDIT the values i am searching for are integers in an array of integers
推荐答案
自从我使用fortran和f2py以来已有一段时间了,但是去年我对cython
做过类似的事情.
It's been sometime since I worked with fortran and f2py, but I did something similar with cython
last year.
在匈牙利算法搜索问题中,我需要在2d数组中找到第一个0值,该值受行和列掩码数组的影响.
In a Hungarian algorithm search problem, I needed to find the first 0 value in a 2d array, subject to row and column masking arrays.
因此,使用where
(argwhere
只是np.transpose(np.where(...))
,函数为:
So using where
(argwhere
is just np.transpose(np.where(...))
, the function was:
def find_a_zero(self):
# find first uncovered 0 cost
rc = np.argwhere((self.cost + self.rc[:,None] + self.cc) == 0)
if rc.shape[0]>0:
return tuple(rc[0])
else:
return None, None
我使用argmax
的速度很好:
def find_a_zero(self):
# big help time wise, 16->10 for n=200
cond = (self.cost + self.rc[:,None] + self.cc) == 0
if np.count_nonzero(cond):
idx = np.unravel_index(np.argmax(cond), cond.shape)
return idx
return None, None
np.where
使用count_nonzero
确定其返回数组的大小. argmax
,当操作布尔值时,拳头True
短路.
np.where
uses count_nonzero
to determine the size of its return arrays. argmax
, when operating on a boolean, short circuits on the fist True
.
此cython
版本的速度更快:
cdef find_a_zero(int[:,:] cost, int[:] row_cover, int[:] col_cover):
n = cost.shape[0]
m = cost.shape[1]
cdef size_t r, c
for r in range(n):
for c in range(m):
if (cost[r,c]==0) and (row_cover[r]==0) and (col_cover[c]==0):
row = r
col = c
return r, c
return -1, -1
如果我的cython
内存正确,则像int[:,:] cost
这样的定义将调用其键入的memoryview.具有高效的低级数组操作.
If my memory of cython
is correct, definitions like int[:,:] cost
invoke its typed memoryview. which has efficient lowlevel array operations.
http://cython.readthedocs.io/en/latest /src/userguide/memoryviews.html
http://csclab.murraystate.edu/~bob.pilgrim /445/munkres.html
这篇关于使用fortran和f2py在数组中搜索比np.where(ar == value)更快的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!