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

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:

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

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

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

Have you looked at StructArrays?

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 Float64s.

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

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

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


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

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)
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.