繁体   English   中英

使用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并编写了这个简单的例程。

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)的建议?

编辑我要搜索的值是整数数组中的整数

自从我与fortran和f2py合作以来已经有一段时间了,但是去年我对cython做过类似的事情。

在匈牙利算法搜索问题中,我需要根据行和列掩码数组在2d数组中找到第一个0值。

因此,使用whereargwhere只是np.transpose(np.where(...)) ,该函数是:

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获得了很好的加速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短路。

使用此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。 具有高效的低级数组操作。

http://cython.readthedocs.io/en/latest/src/userguide/memoryviews.html

http://csclab.murraystate.edu/~bob.pilgrim/445/munkres.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM