朱莉娅语言:查找区间

4

问题: 我希望找到类似于R中的findInterval函数,它接受一个标量和表示区间起点的向量作为输入,并返回标量所属的区间索引。例如在R中:

findInterval(x = 2.6, vec = c(1.1,2.1,3.1,4.1))
#[1] 2

这个讨论中,有人提供了Julia语言实现这种功能的函数(见下一节)。然而,基本的indexin函数也可以完成此任务。我想知道如何使用indexin函数(或其他基本函数)来实现这一点。我知道Julia循环很快,我可以编写一个函数,但如果有内置函数并且这是一个常见问题,我宁愿不这样做。
当我尝试使用相同的数字在R语言中的indexin函数时,结果如下:
indexin([2.6], [1.1 2.1 3.1 4.1])
# 1-element Array{Int64,1}:
# 0

这仅表明2.6不在向量中,因为它(据我理解)是要匹配值而不是将标量放入区间。

上面引用链接的函数(我更改了输入\输出数据类型)

function findInterval(x::Float64,vec::Array{Float64})
    out = zeros(Int,length(x))
    vec = unique(vec)
    sort!(vec)

    for j in 1:length(x)
        if x[j] < vec[1]
            out[1] = 0
        elseif x[j] > vec[end]
            out[end] = 0
        else
            out[j] = searchsortedfirst(vec,x[j])-1 
        end
    end
    return out
end

哪些是按预期工作的:

findInterval(2.6, [1.1 2.1 3.1 4.1])
# 1-element Array{Int64,1}:
# 2

来自SO的相关问题: SO上的其他问题寻找在输入值和向量之间找到精确匹配的索引:


你是否有问题想在这里获得答案?或者你打算让"findInterval"的定义成为答案?如果是这样,如果你将其从问题部分中移除,而是将其作为自己问题的答案发布,那么它会更清晰。这没问题!甚至鼓励这样做!http://meta.stackoverflow.com/questions/250204/can-you-answer-your-own-questions-on-stack-overflow - mbauman
嗨,马特,我正在寻找如何使用基本的Julia函数来执行类似于findInterval函数的操作。根据上面的链接,应该有一种方法可以在不编写自定义函数的情况下完成此操作。 - Stuart
4
如果您的输入向量始终是有序的,那么 searchsortedlast 将实现您想要的功能,尽管您可能希望将其包装在自己的函数中,以检查返回值是否为 0length(vec) 并在输入 x 小于(或大于) vec 中的每个元素时执行您想要的任何行为。 - Colin T Bowers
嗨,感谢@ColinTBowers。那很好用。searchsortedlast([1.1, 2.1, 3.1, 4.1], 2.6)可以完成任务。 - Stuart
1
没问题。我会把它转化为答案。 - Colin T Bowers
1个回答

3
如果您的输入向量始终是有序的,则searchsortedlast将执行您想要的操作,例如:
vec = [1.1, 2.1, 3.1, 4.1]
x = 2.6
searchsortedlast(vec, x)

然而需要注意的是,如果x < vec[1]searchsortedlast将返回0;如果x > vec[end],则会返回length(vec)。所以如果你希望在vec中没有任何区间包含x时总是返回0,你可能需要编写自己的自定义行为来检查这些结果,例如:

function find_interval(vec, x)
    i = searchsortedlast(vec, x)
    i == length(vec) && (i = 0)
    return(i)
 end

另外,如果您经常使用排序向量,您可能会对我为Julia编写的排序向量包感兴趣,但我从未添加到METADATASortedVectors包的源代码在这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接