Julia 我如何洗牌一系列数字,然后将其分割成一定长度的子阵列?
假设我有一个范围Julia 我如何洗牌一系列数字,然后将其分割成一定长度的子阵列?,julia,Julia,假设我有一个范围1:N,我想将该范围随机排列成一个顺序,然后将得到的乱排列数组拆分成最多为128个元素的子数组。我该怎么做 此问题基于JuliaLang slack频道上出现的一个问题。标准库中的函数shuffle可用于将容器随机排列为随机顺序: julia> using Random: shuffle julia> shuffle(1:10) 10-element Array{Int64,1}: 6 9 3 2 10 1 8 7 5 4 J
1:N
,我想将该范围随机排列成一个顺序,然后将得到的乱排列数组拆分成最多为128
个元素的子数组。我该怎么做
此问题基于JuliaLang slack频道上出现的一个问题。标准库中的函数
shuffle
可用于将容器随机排列为随机顺序:
julia> using Random: shuffle
julia> shuffle(1:10)
10-element Array{Int64,1}:
6
9
3
2
10
1
8
7
5
4
Julia的Base
中的函数Iterators.partition
可用于在固定长度的块中迭代iterable:
julia> using Base.Iterators: partition
julia> partition(1:20, 7)
Base.Iterators.PartitionIterator{UnitRange{Int64}}(1:20, 7)
但是,partition
默认返回一个惰性迭代器,因此如果我们想具体化实际结果,我们需要收集它:
julia> collect(partition(1:20, 7))
3-element Array{UnitRange{Int64},1}:
1:7
8:14
15:20
综上所述,我们有
julia> using Random: shuffle
julia> using Base.Iterators: partition
julia> shuffle_partition(N; chunk_size=128) = (collect ∘ partition)(shuffle(1:N), chunk_size)
shuffle_partition (generic function with 1 method)
julia> shuffle_partition(503)
4-element Array{SubArray{Int64,1,Array{Int64,1},Tuple{UnitRange{Int64}},true},1}:
[313, 51, 117, 373, 381, 340, 342, 415, 423, 453 … 201, 178, 167, 242, 2, 76, 146, 439, 363, 448]
[115, 121, 306, 440, 295, 181, 30, 280, 388, 227 … 362, 39, 317, 171, 55, 214, 261, 251, 96, 9]
[486, 248, 161, 319, 325, 176, 80, 369, 434, 209 … 442, 350, 273, 419, 130, 305, 192, 482, 265, 234]
[460, 31, 400, 466, 220, 447, 119, 446, 198, 141 … 226, 438, 74, 152, 203, 303, 378, 231, 458, 194]
julia> length.(ans)
4-element Array{Int64,1}:
128
128
128
119
此答案基于在Slack上找到的答案
parts = view.(Ref(shuffle(1:N)),(i:min(i+k-1, N) for i in 1:k:N))
这假设N
是元素数,分区大小是k
。获得的结果是一个视图列表(因此,无序1:N在内存中只存储一次)。注意如何使用Ref
来避免无序列表上的矢量化
样本测试代码:
julia> using Random
julia> N, k = 20, 4;
julia> parts = view.(Ref(shuffle(1:N)),(i:min(i+k-1, N) for i in 1:k:N))
5-element Array{SubArray{Int64,1,Array{Int64,1},Tuple{UnitRange{Int64}},true},1}:
[18, 15, 1, 6]
[10, 20, 4, 14]
[17, 9, 19, 16]
[5, 8, 12, 3]
[11, 13, 2, 7]
使用迭代器:
我认为最简单的方法是使用randperm(如果值介于1和N之间),所以
应该可以工作。有一个专门的函数来创建置换,randperm(n)
using Base.Iterators: partition
using Random: randperm
N = 513
k = 128
collect(partition(randperm(N), k))