# Sampling without replacement

**URL:** <https://discourse.julialang.org/t/sampling-without-replacement/1073>\
**Category:** Statistics\
**Tags:** statistics\
**Created:** [December 20, 2016, 9:22pm UTC](https://discourse.julialang.org/t/sampling-without-replacement/1073 "2016-12-20T21:22:56Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![SPV](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/spv/32/2606_2.png) [@SPV](https://discourse.julialang.org/u/SPV)\
**Post date:** [December 20, 2016, 9:22pm UTC](https://discourse.julialang.org/t/sampling-without-replacement/1073/1 "2016-12-20T21:22:56Z")

</div>

```julia
rand(1:20, 3)

```

gives three random integers in `[1:20]` with replacement. I see there are some threads on github on this issue, but I am not sure what is the recommended way with Julia 0.5 to sample without replacement.

---

<div class="post-metadata">

**Author:** ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)\
**Post date:** [December 20, 2016, 9:34pm UTC](https://discourse.julialang.org/t/sampling-without-replacement/1073/2 "2016-12-20T21:34:31Z")

</div>

See the `StatsBase` package: [http://juliastats.github.io/StatsBase.jl/stable/sampling.html#Sampling-API-1](http://juliastats.github.io/StatsBase.jl/stable/sampling.html#Sampling-API-1)

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [December 20, 2016, 10:32pm UTC](https://discourse.julialang.org/t/sampling-without-replacement/1073/3 "2016-12-20T22:32:09Z")

</div>

Without using external packages you can use [`randperm`](http://docs.julialang.org/en/stable/stdlib/arrays/#Base.randperm) and take the first three elements:

```julia
randperm(20)[1:3]

```

But this may not be very efficient, as it needs to create first an array of 20 elements.

---

<div class="post-metadata">

**Author:** ![shorty66](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shorty66/32/3254_2.png) [@shorty66](https://discourse.julialang.org/u/shorty66)\
**Post date:** [September 19, 2017, 7:39am UTC](https://discourse.julialang.org/t/sampling-without-replacement/1073/5 "2017-09-19T07:39:36Z")

</div>

You can use `splice!` to pick random elements and remove them from the collection:

```julia
function sample_wo_repl!(A,n)
    sample = Array{eltype(A)}(n)
    for i in 1:n
        sample[i] = splice!(A, rand(eachindex(A)))
    end
    return sample
end

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 19, 2017, 12:05pm UTC](https://discourse.julialang.org/t/sampling-without-replacement/1073/6 "2017-09-19T12:05:49Z")

</div>

There is also `randsubseq` in Base. This efficiently samples an array without replacement, but with a given probability (per element) rather than a given number of elements. e.g. `randsubseq(1:20, 0.15)` produces 3 elements on average.

---

<div class="post-metadata">

**Author:** ![dmerrell](https://avatars.discourse-cdn.com/v4/letter/d/a183cd/32.png) [@dmerrell](https://discourse.julialang.org/u/dmerrell)\
**Post date:** [December 2, 2019, 7:06pm UTC](https://discourse.julialang.org/t/sampling-without-replacement/1073/7 "2019-12-02T19:06:33Z")

</div>

Update: `randperm` and `randsubseq` have been moved from `Base` to `Random`

It’s still probably better to use `StatsBase` to solve this problem.

(Commenting here because this thread is the first result when I google “Julia sample without replacement”)

---

<div class="post-metadata">

**Author:** ![kevin.squire](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevin.squire/32/62_2.png) [@kevin.squire](https://discourse.julialang.org/u/kevin.squire)\
**Post date:** [December 30, 2019, 9:59pm UTC](https://discourse.julialang.org/t/sampling-without-replacement/1073/8 "2019-12-30T21:59:34Z")

</div>

Update: the StatsBase URL has changed (again): [Sampling from Population · StatsBase.jl](https://juliastats.org/StatsBase.jl/stable/sampling/#Sampling-API-1)

---

<div class="post-metadata">

**Author:** ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)\
**Post date:** [December 31, 2019, 6:34am UTC](https://discourse.julialang.org/t/sampling-without-replacement/1073/9 "2019-12-31T06:34:42Z")

</div>

I can’t edit the above post anymore (when I click edit it only shows the history) - seems there is an editing limit?

---

<div class="post-metadata">

**Author:** ![leoflotor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leoflotor/32/35345_2.png) [@leoflotor](https://discourse.julialang.org/u/leoflotor)\
**Post date:** [October 5, 2023, 5:42am UTC](https://discourse.julialang.org/t/sampling-without-replacement/1073/10 "2023-10-05T05:42:56Z")

</div>

This is pretty handy, really. Thanks!

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [October 5, 2023, 5:54am UTC](https://discourse.julialang.org/t/sampling-without-replacement/1073/11 "2023-10-05T05:54:32Z")

</div>

Didn’t see the following in this thread:

```julia
julia> using StatsBase

julia> sample(1:20, 3; replace=false)
3-element Vector{Int64}:
  5
 20
 18

```

and it feels like this is the “canonical” solution.
