# Fancy Arrays: between 1 axis with compound keys, and multiple axes

**URL:** <https://discourse.julialang.org/t/fancy-arrays-between-1-axis-with-compound-keys-and-multiple-axes/80843>\
**Category:** General Usage\
**Created:** [May 10, 2022, 8:16pm UTC](https://discourse.julialang.org/t/fancy-arrays-between-1-axis-with-compound-keys-and-multiple-axes/80843 "2022-05-10T20:16:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [May 10, 2022, 8:16pm UTC](https://discourse.julialang.org/t/fancy-arrays-between-1-axis-with-compound-keys-and-multiple-axes/80843/1 "2022-05-10T20:16:10Z")

</div>

One case i have had recently is wanting to view a AxisKeys KeyedArray that came from some panel data either as a `Matrix` which is keyed by by `location` and `time`;  
or as a `Vector` which is keyed by a `NamedTuple(location=..., time=...)`.

I would describe them former as multiple axes, and the later as 1 axis with a compound key.

Anyone else encountered this, and have a good package for working with it?

Right now I just work with it in compound key form, and write some rather ugly code for filtering based on 1 key by mapping the named tuples one 1 of their fields.

e.,g. right now i have to do on compund keys:

```julia
x[[k.location=="London" for k in axiskeys(x)])

```

but if i could be doing it with multiple axes it would be:

```julia
x[location=Key("London"), time=:]

```

---

<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:** [May 11, 2022, 8:55am UTC](https://discourse.julialang.org/t/fancy-arrays-between-1-axis-with-compound-keys-and-multiple-axes/80843/2 "2022-05-11T08:55:09Z")

</div>

Have you looked at [StructArrays](https://juliaarrays.github.io/StructArrays.jl/stable/)?

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [May 11, 2022, 10:55am UTC](https://discourse.julialang.org/t/fancy-arrays-between-1-axis-with-compound-keys-and-multiple-axes/80843/3 "2022-05-11T10:55:11Z")

</div>

I don’t see the connection?  
The elements of these arrays are not structs.  
The keys of the arrays are structs.  
The elements are just `Float64`s.

---

<div class="post-metadata">

**Author:** ![jacobusmmsmit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jacobusmmsmit/32/217669_2.png) [@jacobusmmsmit](https://discourse.julialang.org/u/jacobusmmsmit)\
**Post date:** [May 11, 2022, 11:03am UTC](https://discourse.julialang.org/t/fancy-arrays-between-1-axis-with-compound-keys-and-multiple-axes/80843/4 "2022-05-11T11:03:00Z")

</div>

Apologies if I’m misunderstanding as KeyedArrays are not something that I’ve come across before, but I don’t see a significant difference between this and a DataFrame in tidy format.

In this case you could just do

```julia
subset(df, :location == "London")

```

Do you require the Matrix structure to perform algebra on your data?

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [May 11, 2022, 11:41am UTC](https://discourse.julialang.org/t/fancy-arrays-between-1-axis-with-compound-keys-and-multiple-axes/80843/6 "2022-05-11T11:41:04Z")

</div>

> [@jacobusmmsmit](#):
>
> Do you require the Matrix structure to perform algebra on your data?

yes

---

<div class="post-metadata">

**Author:** ![visr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/visr/32/17204_2.png) [@visr](https://discourse.julialang.org/u/visr)\
**Post date:** [May 11, 2022, 1:47pm UTC](https://discourse.julialang.org/t/fancy-arrays-between-1-axis-with-compound-keys-and-multiple-axes/80843/7 "2022-05-11T13:47:18Z")

</div>

If I understand correctly you want to do something like this:

```julia
using Dates
using AxisKeys

# construct 2D KeyedArray
data = collect(reshape(1:6, 2, 3))
location=["London", "Paris"]
time = Date(2020, 1):Month(1):Date(2020, 3)
x = KeyedArray(data; location, time)

# try to create a 1D view with compound keys
NT = NamedTuple{dimnames(x), Tuple{eltype.(axiskeys(x))...}}
# compoundkey should really be a lazy vector
compoundkey = NT.(vec(collect(Iterators.product(axiskeys(x)...))))
KeyedArray(vec(data); compoundkey)

```

```julia
1-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓ compoundkey ∈ 6-element Vector{NamedTuple{(:location, :time), Tuple{String, Date}}}
And data, 6-element Vector{Int64}:
  (location = "London", time = Date("2020-01-01")) 1
  (location = "Paris", time = Date("2020-01-01")) 2
  (location = "London", time = Date("2020-02-01")) 3
  (location = "Paris", time = Date("2020-02-01")) 4
  (location = "London", time = Date("2020-03-01")) 5
  (location = "Paris", time = Date("2020-03-01")) 6

```

But I guess having to allocate the size N `compoundkey` here defeats the point (the data itself is a view). I’m not sure how to do that. I guess one could create a lazy `CompoundKeys` struct with such properties.

Would it make sense for `vec(x)` or `reshape(x, :)` to return such a 1D view? Currently those only return the data itself.
