2014-01-16 47 views
7

有沒有一種巧妙的方式來重寫這個Julia函數,也許只需要使用1行代碼,而不會太慢? (我剛開始使用Julia,太棒了!)K是一個正整數,zd是一個不大於K的正整數向量。謝謝!在1行代碼中計算矢量中每個唯一整數的實例?

function tally(zd) 
    ret = zeros(Int64, K) 
    for k in zd 
     ret[k] += 1 
    end 
    return ret 
end 

實施例:

julia> K = 5 
julia> zd = [1,2,2,2,2,3]; 
julia> tally(zd) 
5-element Array{Float64,1}: 
1 
4 
1 
0 
0 
+2

這看起來很漂亮。 –

+1

我想我已經考慮過使用'reduce'或'fold'之類的1行解決方案,並且我也只是對其他方法感到好奇,但是您說得對,這可能足夠好。我喜歡下面的建議來使用'hist'。我想我會這樣做。感謝所有的反饋! – Jeff

回答

5

我還沒有測試的性能,但使用HIST函數應該工作:

hist(zd,0.5:K+0.5)[2] 

給出:

5-元件陣列{ Int64,1}:

,或者,如果零是不重要的,只要使用

hist(zd)[2] 
3-element Array{Int64,1}: 
1 
4 
1 
8

任何替代方案可能不會更快。你的循環已經只有一個通過數組。 Julia循環速度很快,而且與其他語言一樣,矢量化代碼沒有速度優勢。

看看Julia的hist函數的實現。這是直接取自Julia Standard Library

function hist(v::AbstractVector, edg::AbstractVector) 
    n = length(edg)-1 
    h = zeros(Int, n) 
    for x in v 
     i = searchsortedfirst(edg, x)-1 
     if 1 <= i <= n 
      h[i] += 1 
     end 
    end 
    edg,h 
end 

的「EDG」參數包含箱的邊緣。如果我們刪除了這個功能,我們就得到了你寫的功能。

+0

僅供參考,如果在此處詳細說明,則可能會有速度優勢: https://software.intel.com/en-us/articles/vectorization-in-julia 另請參閱@simd here:http://docs.julialang。組織/ EN /釋放-0。4 /手動/性能提示/它在某些情況下是實驗性的,並警告它可能會被刪除..但考慮到性能的好處,我懷疑它。 –

3

StatsBase.jl包中包含a bunch of counting functions。您的理貨功能相當於counts(zd, 1:K)

也有計算除整數以外的類型的唯一元素的方法,例如countmap,它返回一個將唯一值映射到其出現次數的字典。

2

我知道它老了,但它怎麼樣

[sum(zd .== i) for i in unique(zd)]

在很短的測試成績比你最初的功能(時間和內存方面)較好。

注意:結果沒有排序!

相關問題