使用fortran和f2py在数组中搜索比np.where(ar == value)更快的值 [英] Searching an array for a value faster than np.where(ar==value) using fortran and f2py

查看:131
本文介绍了使用fortran和f2py在数组中搜索比np.where(ar == value)更快的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆