Вы можете использовать генератор с условием if
, например:
[v for v in g if rand() < 0.01]
или если вы хотите немного более быстрый, но более подробный подход (я жестко закодировал 0.01
и тип элемента g
, и я предполагаю, что ваш генератор поддерживает length
- в противном случае вы можете удалить строку sizehint!
):
function collect_sample(g)
r = Int[]
sizehint!(r, round(Int, length(g) * 0.01))
for v in g
if rand() < 0.01
push!(r, v)
end
end
r
end
EDIT
Здесь у вас есть примеры самозапускающегося пробоотборника и пробоотборника резервуара, дающего вам фиксированный выходной размер. Чем меньше доля ввода, которую вы хотите получить, тем лучше использование самозапускающегося сэмплера:
function self_avoiding_sampler(source_size, ith, target_size)
rng = 1:source_size
idx = rand(rng)
x1 = ith(idx)
r = Vector{typeof(x1)}(undef, target_size)
r[1] = x1
s = Set{Int}(idx)
sizehint!(s, target_size)
for i = 2:target_size
while idx in s
idx = rand(rng)
end
@inbounds r[i] = ith(idx)
push!(s, idx)
end
r
end
function reservoir_sampler(g, target_size)
r = Vector{Int}(undef, target_size)
for (i, v) in enumerate(g)
if i <= target_size
@inbounds r[i] = v
else
j = rand(1:i)
if j < target_size
@inbounds r[j] = v
end
end
end
r
end