Is there a slick way to rewrite this Julia function, perhaps using just 1 line of code, without making it much slower? (I just started using Julia. It's great!) K
is a positive integer and zd
is a vector of positive integers no greater than K
. Thanks!
function tally(zd)
ret = zeros(Int64, K)
for k in zd
ret[k] += 1
end
return ret
end
Example:
julia> K = 5
julia> zd = [1,2,2,2,2,3];
julia> tally(zd)
5-element Array{Float64,1}:
1
4
1
0
0
I know its old but how about
[sum(zd .== i) for i in unique(zd)]
in a short test it performed better than your initial function (time and memory wise).
Caution: result not sorted!
Here http://statsbasejl.readthedocs.org/en/latest/counts.html#countmap
Any alternative probably will not be faster. Your loop already does only one pass through the array. Julia loops are fast, and there is no speed advantage to vectorized code, as there is in other languages.
Have a look at Julia's implementation of the
hist
function. This is taken directly from the Julia Standard Library:The "edg" parameter contains the edges of the bins. If we remove that feature, we get exactly the function you wrote.
There are a bunch of counting functions included in the StatsBase.jl package. Your tally function is equivalent to
counts(zd, 1:K)
.There are also methods for counting unique elements of types other than integer, too, such as
countmap
, which returns a dictionary mapping unique values to their number of occurrences.I haven't tested the performance, but using the hist function should work:
gives:
5-element Array{Int64,1}: 1 4 1 0 0
or, if the zeros are unimportant, just use