# Slicing a Vector into a Matrix using views

**URL:** <https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918>\
**Category:** General Usage\
**Tags:** vector, views, matrix\
**Created:** [March 13, 2025, 2:05pm UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918 "2025-03-13T14:05:51Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ju\_ska](https://avatars.discourse-cdn.com/v4/letter/j/ecd19e/32.png) [@Ju\_ska](https://discourse.julialang.org/u/Ju_ska)\
**Post date:** [March 13, 2025, 2:05pm UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/1 "2025-03-13T14:05:51Z")

</div>

Hi,

I loaded data from a simple file input.txt:

```julia
 1
 2
 3
 4
 5
 6
 7
 8
 9

```

into a vector with:

```julia
data = CSV.File("input.txt", ntasks=1, header=false).Column1

```

So it’s equivalent to:

```julia
julia> data = [1,2,3,4,5,6,7,8,9]
9-element Vector{Int64}:
 1
 2
 3
 4
 5
 6
 7
 8
 9

```

Now I would like to transform it into a fixed number of groups, e.g. r = 3, stored in a Matrix this way:

```julia
1 2 3 4 5 6 7
2 3 4 5 6 7 8
3 4 5 6 7 8 9

```

I could fill a new Matrix with loops, but for performance reason, I’d prefer not to copy the values, so I guess using @view would be better.  
I don’t know what would be a clever way to do that.

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [March 13, 2025, 2:39pm UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/2 "2025-03-13T14:39:17Z")

</div>

Making your own `AbstractArray` types in Julia is [beautifully easy](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array):

```julia
struct Shift1Matrix{T, V<:AbstractVector{T}} <: AbstractMatrix{T}
    v::V # data
    sz1::Int # height
end

Base.size(x::Shift1Matrix) = (x.sz1, length(x.v) - x.sz1 + 1)
Base.getindex(x::Shift1Matrix, i::Int, j::Int) = x.v[i + j - 1]

```

```julia-repl
julia> Shift1Matrix(1:9, 3)
3×7 Shift1Matrix{Int64, UnitRange{Int64}}:
 1 2 3 4 5 6 7
 2 3 4 5 6 7 8
 3 4 5 6 7 8 9

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [March 13, 2025, 2:50pm UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/3 "2025-03-13T14:50:45Z")

</div>

For those of us not as smart as mikmoore, an alternative:

```julia
using LazyStack
using ShiftedArrays: circshift as SA_circshift

data = [1,2,3,4,5,6,7,8,9]
n = length(data)
r = 3
m = transpose(lazystack(view(SA_circshift(data, i), 1:n-r+1) for i in 0:-1:-r+1))

```

---

<div class="post-metadata">

**Author:** ![Ju\_ska](https://avatars.discourse-cdn.com/v4/letter/j/ecd19e/32.png) [@Ju\_ska](https://discourse.julialang.org/u/Ju_ska)\
**Post date:** [March 13, 2025, 4:12pm UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/4 "2025-03-13T16:12:39Z")

</div>

I wish I’d better know Julia…

Thanks everyone !

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [March 13, 2025, 7:15pm UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/5 "2025-03-13T19:15:15Z")

</div>

```julia
l=length(data)
rsp(l,r)=[i:r+i-1 for i in 1:l-r+1]
v=rsp(l,3)

stack(view.([data],v))

```

```julia
using BenchmarkTools
using LazyStack
julia> @btime LazyStack.stack(view.($[data],$v))
  47.017 ns (1 allocation: 336 bytes)
3×7 stack(::Vector{SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}}) with eltype Int64:
 1 2 3 4 5 6 7
 2 3 4 5 6 7 8
 3 4 5 6 7 8 9

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [March 13, 2025, 8:21pm UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/6 "2025-03-13T20:21:51Z")

</div>

@rocco_sprmnt21, it seems simpler to write like this:

```julia
using LazyStack
data = collect(1:9)
n = length(data)
r = 3
lazystack(view(data, i:r+i-1) for i in 1:n-r+1)

# result:
3×7 Matrix{Int64}:
 1 2 3 4 5 6 7
 2 3 4 5 6 7 8
 3 4 5 6 7 8 9

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [March 13, 2025, 8:38pm UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/7 "2025-03-13T20:38:28Z")

</div>

There doesn’t seem to be a lazystack function in my system.  
However, these are the results they get with the following variations:

```julia
julia> @btime Base.stack(view.($[data],$v))
  116.936 ns (2 allocations: 560 bytes)
3×7 Matrix{Int64}:
 1 2 3 4 5 6 7
 2 3 4 5 6 7 8
 3 4 5 6 7 8 9

julia> @btime LazyStack.stack(view.($[data],$v))
  69.176 ns (1 allocation: 336 bytes)
3×7 stack(::Vector{SubArray{Int64, 1, Vector{Int64}, Tuple{UnitRange{Int64}}, true}}) with eltype Int64:
 1 2 3 4 5 6 7
 2 3 4 5 6 7 8
 3 4 5 6 7 8 9

julia> @btime LazyStack.stack(view($data, i:r+i-1) for i in 1:n-r+1)
  2.760 μs (38 allocations: 1.31 KiB)
3×7 Matrix{Int64}:
 1 2 3 4 5 6 7
 2 3 4 5 6 7 8
 3 4 5 6 7 8 9

```

```julia
julia> using IterTools
julia> @btime Base.stack(partition($data,3,1))
  44.332 ns (1 allocation: 224 bytes)
3×7 Matrix{Int64}:
 1 2 3 4 5 6 7
 2 3 4 5 6 7 8
 3 4 5 6 7 8 9

```

LazyStack.stack does not work with this type of iterator

```julia
julia> @btime LazyStack.stack(partition($data,3,1))
ERROR: MethodError: no method matching stack(::IterTools.Partition{Vector{Int64}, 3, 1})
You may have intended to import Base.stack

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [March 13, 2025, 8:49pm UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/8 "2025-03-13T20:49:59Z")

</div>

I have used LazyStack v0.1.3, and `lazystack()` is really the first example provided in the package page [GitHub - mcabbott/LazyStack.jl: 🥞](https://github.com/mcabbott/LazyStack.jl)

But now I am confused because this page shows v0.1.1 as the current version… @mcabbott ?

Anyway, your solution using Base `stack()` and IterTools.jl `partition()` seems to be the winning combo.

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [March 13, 2025, 9:06pm UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/9 "2025-03-13T21:06:58Z")

</div>

> [@rafael.guerra](#):
>
> Anyway, your solution using Base `stack()` and IterTools,jl `partition()` seems to be the winning combo.

it is certainly very flexible (being able to choose as parameters the number of rows and the shift) and easy to use.  
Maybe it would be even better if lazystack were to put together the pieces of the partition.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [March 13, 2025, 10:02pm UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/10 "2025-03-13T22:02:30Z")

</div>

Honestly, I wouldn’t be surprised if such views performed worse than copying the data. Copies are surprisingly cheap. And accessing views — especially views that use non-range indices — can be surprisingly expensive. The tradeoff will depend upon how you use the view.

Profile!

It’s also worth noting that you can just index directly with a matrix of indices. Or broadcast. And with broadcasting, you can possibly fuse with downstream operations, too.

```julia-repl
julia> data = [1,2,3,4,5,6,7,8,9];

julia> r = 3;

julia> data[(begin:begin+r-1) .+ (0:end-r)']
3×7 Matrix{Int64}:
 1 2 3 4 5 6 7
 2 3 4 5 6 7 8
 3 4 5 6 7 8 9

julia> getindex.((data,), (1:r) .+ (0:9-r)')
3×7 Matrix{Int64}:
 1 2 3 4 5 6 7
 2 3 4 5 6 7 8
 3 4 5 6 7 8 9

```

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [March 14, 2025, 7:50am UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/11 "2025-03-14T07:50:14Z")

</div>

There’s also:

```julia
julia> using ToeplitzMatrices, FFTW

julia> Hankel(1:9, (3,7))
3×7 Hankel{Int64, UnitRange{Int64}, Tuple{Int64, Int64}}:
 1 2 3 4 5 6 7
 2 3 4 5 6 7 8
 3 4 5 6 7 8 9

```

Not only does this provide a memory-efficient representation, but it also provides some specialized linear algebra routines.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [March 14, 2025, 7:59am UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/12 "2025-03-14T07:59:19Z")

</div>

Why do you need FFTW ?

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [March 14, 2025, 8:02am UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/13 "2025-03-14T08:02:40Z")

</div>

~~You don’t. I quickly browsed the readme for ToeplitzMatrices.jl and it looked like it was useful, but on closer inspection that only applies to circulant matrices. Will edit my post.~~

On even closer inspection: multiplying by a large Toeplitz (or Hankel) matrix is done using an FFT. So even though. FFTW is not needed for the small example, it is likely to be useful in practice.

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [March 16, 2025, 11:06am UTC](https://discourse.julialang.org/t/slicing-a-vector-into-a-matrix-using-views/126918/14 "2025-03-16T11:06:07Z")

</div>

```julia
function hm(data,r,s)
    n=length(data)
    c=length(r:s:n)
    ci=CartesianIndices((r,c))
    HM=Matrix{Int}(undef,r,c)
    @inbounds for i in ci
        HM[i]= data[i.I[1]+s*(i.I[2]-1)]
    end
    HM
end

```

Just to show how much I appreciate mbauman’s elegant solution

```julia
f(data,r,s)=getindex.((data,), (1:r) .+ (0:s:9-r)')

```
