# Is there a NamedArray or DimensionalData type package that can combine orthogonal dimensions?

**URL:** <https://discourse.julialang.org/t/is-there-a-namedarray-or-dimensionaldata-type-package-that-can-combine-orthogonal-dimensions/89610>\
**Category:** General Usage\
**Tags:** namedarrays, axiskeys, dimensionaldata\
**Created:** [November 1, 2022, 10:38am UTC](https://discourse.julialang.org/t/is-there-a-namedarray-or-dimensionaldata-type-package-that-can-combine-orthogonal-dimensions/89610 "2022-11-01T10:38:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [November 1, 2022, 10:38am UTC](https://discourse.julialang.org/t/is-there-a-namedarray-or-dimensionaldata-type-package-that-can-combine-orthogonal-dimensions/89610/1 "2022-11-01T10:38:35Z")

</div>

Vectorised operations on regular arrays produce a cross product across dimensions. e.g.

```julia
x = [1 2 3]

a = reshape( x, (3,1,1))
b = reshape( x, (1,3,1))
c = reshape( x, (1,1,3))

X = @. a + b + c

X[3,3,3] # =9

```

Similarly, is there a package that allows something like:

```julia
@dimensions begin
    Currency => [USD, GBP, EUR]
    Date => [Date(2022,1,1), Date(2022,1,2), Date(2022,1,3)]
    Scenario => [1, 2, 3]
end

a = NammedArray( x, Currency )
b = NammedArray( x, Date )
c = NammedArray( x, Scenario )

X = @. a + b + c #NammedArray across Currency, Date and Scenario dimensions

X[EUR, Date(2022,1,3), 3] # =9

```

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [November 1, 2022, 12:07pm UTC](https://discourse.julialang.org/t/is-there-a-namedarray-or-dimensionaldata-type-package-that-can-combine-orthogonal-dimensions/89610/2 "2022-11-01T12:07:55Z")

</div>

It’s not so hard to do, by fiddling with broadcasting… making this happen automatically means these things are less like arrays.

At some point I made [a package](https://github.com/mcabbott/NamedPlus.jl) which asked you to specify the names (and the order!) before inserting the necessary permutations:

```julia
julia> using NamedPlus, AxisKeys, Dates

julia> begin
         x = [1,2,3]
         
         currency = [:USD, :GBP, :EUR]
         date = [Date(2022,1,1), Date(2022,1,2), Date(2022,1,3)]
         scenario = ["one", "two", "three"]
         
         a = NamedDimsArray(x; currency)
         b = NamedDimsArray(x; date)
         c = NamedDimsArray(x; scenario)
       end
1-dimensional NamedDimsArray(KeyedArray(...)) with keys:
↓ scenario ∈ 3-element Vector{String}
And data, 3-element Vector{Int64}:
 ("one") 1
 ("two") 2
 ("three") 3

julia> @named out{date, currency} = a .+ b
3×3 NamedDimsArray(::Matrix{Int64}, (:date, :currency)):
        → currency
↓ date 2 3 4
        3 4 5
        4 5 6

julia> @named out{date, currency, scenario} = a .+ b ./ c
3×3×3 NamedDimsArray(::Array{Float64, 3}, (:date, :currency, :scenario)):
[:, :, scenario=1] → currency
↓ date 2.0 3.0 4.0
        3.0 4.0 5.0
        4.0 5.0 6.0

[:, :, scenario=2] → currency
↓ date 1.5 2.5 3.5
        2.0 3.0 4.0
        2.5 3.5 4.5

[:, :, scenario=3] → currency
↓ date 1.33333 2.33333 3.33333
        1.66667 2.66667 3.66667
        2.0 3.0 4.0

julia> let names = (:date, :currency, :scenario)
         align(a, names)
       end
2-dimensional NamedDimsArray(KeyedArray(...)) with keys:
↓ _ ∈ 1-element OneTo{Int}
→ currency ∈ 3-element Vector{Symbol}
And data, 1×3 transpose(::Vector{Int64}) with eltype Int64:
      (:USD) (:GBP) (:EUR)
 (1) 1 2 3

julia> let names = (:date, :currency, :scenario)
         align(a, names) .+ align(b, names) ./ align(c, names)
       end
3-dimensional NamedDimsArray(KeyedArray(...)) with keys:
↓ date ∈ 3-element Vector{Date}
→ currency ∈ 3-element Vector{Symbol}
◪ scenario ∈ 3-element OneTo{Int}
And data, 3×3×3 Array{Float64, 3}:
[:, :, 1] ~ (:, :, 1):
                        (:USD) (:GBP) (:EUR)
   Date("2022-01-01") 2.0 3.0 4.0
   Date("2022-01-02") 3.0 4.0 5.0
   Date("2022-01-03") 4.0 5.0 6.0

[:, :, 2] ~ (:, :, 2):
                        (:USD) (:GBP) (:EUR)
   Date("2022-01-01") 1.5 2.5 3.5
   Date("2022-01-02") 2.0 3.0 4.0
   Date("2022-01-03") 2.5 3.5 4.5

[:, :, 3] ~ (:, :, 3):
                        (:USD) (:GBP) (:EUR)
   Date("2022-01-01") 1.33333 2.33333 3.33333
   Date("2022-01-02") 1.66667 2.66667 3.66667
   Date("2022-01-03") 2.0 3.0 4.0

```

I’m not sure why the KeyedArray wrapper has gone missing in the macro version. NamedPlus is a bit experimental!

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [November 2, 2022, 1:11am UTC](https://discourse.julialang.org/t/is-there-a-namedarray-or-dimensionaldata-type-package-that-can-combine-orthogonal-dimensions/89610/3 "2022-11-02T01:11:03Z")

</div>

`@named out{date, currency} = a .+ b`

that’s really nice syntax.  
Unfortunately NamedPlus wouldn’t install on my machine.  
I’ll try again later.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [November 2, 2022, 1:18am UTC](https://discourse.julialang.org/t/is-there-a-namedarray-or-dimensionaldata-type-package-that-can-combine-orthogonal-dimensions/89610/4 "2022-11-02T01:18:44Z")

</div>

`broadcast_dims` in DimensionalData.jl will probably do what you want. It permutes and reshapes so that the output has the dimensions of all the input arrays.

I guess someone could make it a macro so it feels more like regular broadcast, but I don’t want to mix it with normal syntax.

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [November 2, 2022, 1:29am UTC](https://discourse.julialang.org/t/is-there-a-namedarray-or-dimensionaldata-type-package-that-can-combine-orthogonal-dimensions/89610/5 "2022-11-02T01:29:44Z")

</div>

Thanks Raf. I’ll check it out
