How can I get the chunks of a given array

I’ve a series of 60 elements:

series = [30,21,29,31,40,48,53,47,37,39,31,29,17,9,20,24,27,35,41,38,
          27,31,27,26,21,13,21,18,33,35,40,36,22,24,21,20,17,14,17,19,
          26,29,40,31,20,24,18,26,17,9,17,21,28,32,46,33,23,28,22,27,
          18,8,17,21,31,34,44,38,31,30,26,32];

I want to convert it to an array of 6 elements, where each element is an array of 12 elements

I tried reshape:

zx = reshape(series, 12, :)

That generates another array of elements as:

12×6 Array{Int64,2}:
 30  17  21  17  17  18
 21   9  13  14   9   8
 29  20  21  17  17  17
 31  24  18  19  21  21
 40  27  33  26  28  31
 48  35  35  29  32  34
 53  41  40  40  46  44
 47  38  36  31  33  38
 37  27  22  20  23  31
 39  31  24  24  28  30
 31  27  21  18  22  26
 29  26  20  26  27  32

But this does not looks to be what I want, I need to have it as:

12-element Array{Array{Int64,1},1}:
 [1 2 … 11 12]
 [1 2 … 11 12]
 [1 2 … 11 12]
 [1 2 … 11 12]
 [1 2 … 11 12]
 [1 2 … 11 12]
 [1 2 … 11 12]
 [1 2 … 11 12]
 [1 2 … 11 12]
 [1 2 … 11 12]
 [1 2 … 11 12]
 [1 2 … 11 12]

In some functional programming languages, this is called chunk, so I need to have my series converted to chunks of 12 elements each

One way you could do that is:

[series[i:i+11] for i in 1:12:length(series)]
6-element Array{Array{Int64,1},1}:
 [30, 21, 29, 31, 40, 48, 53, 47, 37, 39, 31, 29]
 [17, 9, 20, 24, 27, 35, 41, 38, 27, 31, 27, 26]
 [21, 13, 21, 18, 33, 35, 40, 36, 22, 24, 21, 20]
 [17, 14, 17, 19, 26, 29, 40, 31, 20, 24, 18, 26]
 [17, 9, 17, 21, 28, 32, 46, 33, 23, 28, 22, 27]
 [18, 8, 17, 21, 31, 34, 44, 38, 31, 30, 26, 32]

Thanks, now I can convert this Rust code:

fn initial_seasonal_components (series: &[i32], slen: usize) -> Vec<f32> {
    let n_seasons = series.len() / slen;
    // # compute season averages
    let season_averages = series //season_averages
        .chunks(slen)
        .map(|chunk| chunk.iter().sum::<i32>() as f32 / chunk.len() as f32)
        .collect::<Vec<f32>>();
    // # compute initial values
    (0..slen).map(|i| {
        let mut sum_of_vals_over_avg = 0.0;
        for j in 0..n_seasons {
            sum_of_vals_over_avg += series[i + j * slen] as f32 - season_averages[j] as f32;
        }
        sum_of_vals_over_avg / n_seasons as f32
    }).collect()
}

To Julia as:

season_averages = map(i -> sum(i) / length(i) ,[series[i:i+11] for i in 1:12:length(series)])

map(i -> begin
            sum_of_vals_over_avg = 0.0
            map(j -> # for j in (0:6-1)
                sum_of_vals_over_avg += series[i + j * 12] - season_averages[j+1]
            , (0:6-1)) #end
            sum_of_vals_over_avg / 6
    end
    , (1:12))

You can also use Iterators.partition, which is also lazy.

Iterators.partition(series,12) |> collect
6-element Array{Array{Int64,1},1}:
 [30, 21, 29, 31, 40, 48, 53, 47, 37, 39, 31, 29]
 [17, 9, 20, 24, 27, 35, 41, 38, 27, 31, 27, 26]
 [21, 13, 21, 18, 33, 35, 40, 36, 22, 24, 21, 20]
 [17, 14, 17, 19, 26, 29, 40, 31, 20, 24, 18, 26]
 [17, 9, 17, 21, 28, 32, 46, 33, 23, 28, 22, 27]
 [18, 8, 17, 21, 31, 34, 44, 38, 31, 30, 26, 32]
5 Likes

or

using Statistics
zx = 1.0*reshape(series, 12, :)
 zx .-= mean(zx, dims=1)
mean(zx, dims=2)
1 Like

Thanks a lot, but I prefer have it pure depending in the language support, and not using Packages unless there is no way to do it using simple commands from the language design and structure itself,

Statistics is a module in base julia, it’s not a separate package

1 Like

aha, thanks a lot for the notification, I was not aware