向量中元素的出现次数[JULIA]

vin*_*cet 2 vector julia

我有一个由重复值和NaN值组成的2500个值的向量.我想删除所有NaN值并计算每个其他值的出现次数.

y
2500-element Array{Int64,1}:
8
43
NaN
46
NaN
8
8
3
46
NaN
Run Code Online (Sandbox Code Playgroud)

例如:8的出现次数为3次,46次出现次数为2次,出现次数为43次为1次.

Mic*_*gge 8

要删除NaN值,可以使用过滤器功能.来自朱莉娅的文档:

过滤器(功能,集合)

返回集合的副本,删除函数为false的元素.

x = filter(y->!isnan(y),y)
filter!(y->!isnan(y),y)
Run Code Online (Sandbox Code Playgroud)

因此,我们创建条件!isnan(y)并使用它来过滤数组y(注意,我们也可以filter(z->!isnan(z),y)使用z我们选择的任何其他变量,因为第一个参数filter只是定义内联函数).注意,我们可以将其保存为新对象,也可以使用"就地修改"版本,!以便通过简单的方式修改现有对象y

然后,在此之前或之后,根据我们是否要NaN在计数中包含s,我们可以使用countmap()StatsBase中的函数.来自朱莉娅的文档:

countmap(x)的

返回一个字典,将x中的每个唯一值映射到其出现次数.

using StatsBase
a = countmap(y)
Run Code Online (Sandbox Code Playgroud)

然后,您可以访问此词典的特定元素,例如,a[-1]它将告诉您有多少次出现-1

或者,如果您想将该字典转换为数组,则可以使用:

b = hcat([[key, val] for (key, val) in a]...)'
Run Code Online (Sandbox Code Playgroud)

注意:感谢@JeffBezanon对过滤NaN值的正确方法的评论.


DNF*_*DNF 6

countmap是迄今为止我见过的最好的解决方案,但这里有一个书面版本,只是稍微慢一些。它只传递数组一次,所以如果你有很多唯一值,它是非常有效的:

function countmemb1(y)
    d = Dict{Int, Int}()
    for val in y
        if isnan(val)
            continue
        end
        if val in keys(d)
            d[val] += 1
        else
            d[val] = 1
        end
    end
    return d
end
Run Code Online (Sandbox Code Playgroud)

如果唯一值的数量非常少,则接受的答案中的解决方案可能会更快一些,但否则扩展性很差。

编辑:因为我无法单独处理,所以这里有一个更通用且速度更快的版本(countmap例如,不接受字符串、集合或元组):

function countmemb(itr)
    d = Dict{eltype(itr), Int}()
    for val in itr
        if isa(val, Number) && isnan(val)
            continue
        end
        d[val] = get(d, val, 0) + 1
    end
    return d
end
Run Code Online (Sandbox Code Playgroud)


Fel*_*ema 5

y=rand(1:10,20)
u=unique(y)
d=Dict([(i,count(x->x==i,y)) for i in u])
println("count for 10 is $(d[10])")
Run Code Online (Sandbox Code Playgroud)