我有一个由重复值和NaN
值组成的2500个值的向量。我想删除所有NaN
值并计算每个其他值的出现次数。
y
2500-element Array{Int64,1}:
8
43
NaN
46
NaN
8
8
3
46
NaN
例如: 8的出现次数为3次 46的出现次数为2次 43的出现次数为1。
答案 0 :(得分:7)
要删除NaN
值,您可以使用过滤器功能。来自Julia docs:
过滤(功能,收藏)
返回集合的副本,删除函数为false的元素。
x = filter(y->!isnan(y),y)
filter!(y->!isnan(y),y)
因此,我们将条件!isnan(y)
创建为我们的函数并使用它来过滤数组y
(注意,我们也可以使用filter(z->!isnan(z),y)
编写z
或任何我们选择的其他变量,因为filter
的第一个参数只是定义内联函数)。请注意,我们可以将其另存为新对象,也可以使用!
发出的修改就地版本,以便只修改现有对象y
然后,在此之前或之后,根据我们是否要在计数中包含NaN
,我们可以使用StatsBase中的countmap()
函数。来自Julia docs:
<强> countmap(x)的强>
返回一个字典,将x中的每个唯一值映射到其中 发生。
using StatsBase
a = countmap(y)
然后,您可以访问此词典的特定元素,例如a[-1]
会告诉您-1
的出现次数
或者,如果您想将该字典转换为数组,则可以使用:
b = hcat([[key, val] for (key, val) in a]...)'
注意:感谢@JeffBezanon对过滤NaN
值的正确方法的评论。
答案 1 :(得分: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])")
答案 2 :(得分:2)
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
如果存在非常少量的唯一值,则接受答案中的解决方案可能会快一些,但其他方面的扩展性会很差。
编辑:因为我不能单独留下,所以这是一个更通用且更快的版本(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