How do I select a random item from a weighted array in Julia?
Use the StatsBase.jl
package, i.e.
Pkg.add("StatsBase") # Only do this once, obviouslyusing StatsBaseitems = ["a", 2, 5, "h", "hello", 3]weights = [0.1, 0.1, 0.2, 0.2, 0.1, 0.3]sample(items, Weights(weights))
Or if you want to sample many:
# With replacementmy_samps = sample(items, Weights(weights), 10)# Without replacementmy_samps = sample(items, Weights(weights), 2, replace=false)
(In Julia < 1.0, Weights
was called WeightVec
).
You can learn more about Weights
and why it exists in the docs. The sampling algorithms in StatsBase
are very efficient and designed to use different approaches depending on the size of the input.
Here's a much simpler approach which only uses Julia's base library:
sample(items, weights) = items[findfirst(cumsum(weights) .> rand())]
Example:
>>> sample(["a", 2, 5, "h", "hello", 3], [0.1, 0.1, 0.2, 0.2, 0.1, 0.3])"h"
This is less efficient than StatsBase.jl
, but for small vectors it's fine.
Also, if weights
is not a normalized vector, you need to do: cumsum(weights ./ sum(weights))
.