|
47 | 47 | # compute mode, given the range of integer values |
48 | 48 | """ |
49 | 49 | mode(a, [r]) |
| 50 | + mode(a::AbstractArray, wv::AbstractWeights) |
50 | 51 |
|
51 | 52 | Return the mode (most common number) of an array, optionally |
52 | | -over a specified range `r`. If several modes exist, the first |
53 | | -one (in order of appearance) is returned. |
| 53 | +over a specified range `r` or weighted via a vector `wv`. |
| 54 | +If several modes exist, the first one (in order of appearance) is returned. |
54 | 55 | """ |
55 | 56 | function mode(a::AbstractArray{T}, r::UnitRange{T}) where T<:Integer |
56 | 57 | isempty(a) && throw(ArgumentError("mode is not defined for empty collections")) |
|
75 | 76 |
|
76 | 77 | """ |
77 | 78 | modes(a, [r])::Vector |
| 79 | + mode(a::AbstractArray, wv::AbstractWeights)::Vector |
78 | 80 |
|
79 | 81 | Return all modes (most common numbers) of an array, optionally over a |
80 | | -specified range `r`. |
| 82 | +specified range `r` or weighted via vector `wv`. |
81 | 83 | """ |
82 | 84 | function modes(a::AbstractArray{T}, r::UnitRange{T}) where T<:Integer |
83 | 85 | r0 = r[1] |
@@ -158,6 +160,47 @@ function modes(a) |
158 | 160 | return [x for (x, c) in cnts if c == mc] |
159 | 161 | end |
160 | 162 |
|
| 163 | +# Weighted mode of arbitrary vectors of values |
| 164 | +function mode(a::AbstractVector, wv::AbstractWeights{T}) where T <: Real |
| 165 | + isempty(a) && throw(ArgumentError("mode is not defined for empty collections")) |
| 166 | + length(a) == length(wv) || |
| 167 | + throw(ArgumentError("data and weight vectors must be the same size, got $(length(a)) and $(length(wv))")) |
| 168 | + |
| 169 | + # Iterate through the data |
| 170 | + mv = first(a) |
| 171 | + mw = first(wv) |
| 172 | + weights = Dict{eltype(a), T}() |
| 173 | + for (x, w) in zip(a, wv) |
| 174 | + _w = get!(weights, x, zero(T)) + w |
| 175 | + if _w > mw |
| 176 | + mv = x |
| 177 | + mw = _w |
| 178 | + end |
| 179 | + weights[x] = _w |
| 180 | + end |
| 181 | + |
| 182 | + return mv |
| 183 | +end |
| 184 | + |
| 185 | +function modes(a::AbstractVector, wv::AbstractWeights{T}) where T <: Real |
| 186 | + isempty(a) && throw(ArgumentError("mode is not defined for empty collections")) |
| 187 | + length(a) == length(wv) || |
| 188 | + throw(ArgumentError("data and weight vectors must be the same size, got $(length(a)) and $(length(wv))")) |
| 189 | + |
| 190 | + # Iterate through the data |
| 191 | + mw = first(wv) |
| 192 | + weights = Dict{eltype(a), T}() |
| 193 | + for (x, w) in zip(a, wv) |
| 194 | + _w = get!(weights, x, zero(T)) + w |
| 195 | + if _w > mw |
| 196 | + mw = _w |
| 197 | + end |
| 198 | + weights[x] = _w |
| 199 | + end |
| 200 | + |
| 201 | + # find values corresponding to maximum counts |
| 202 | + return [x for (x, w) in weights if w == mw] |
| 203 | +end |
161 | 204 |
|
162 | 205 | ############################# |
163 | 206 | # |
|
0 commit comments