Stream: helpdesk (published)

Topic: AxisKeys and Dictionaries


view this post on Zulip mbaz (Mar 16 2023 at 02:19):

I have a 3x3x3 array and I'd like to use "labels" for indexing. I've looked at most of the implementations out there, for example AxisKeys.jl. However, I'd like to do indexing with the labels, and no package seems to support it. From AxisKeys' readme:

using AxisKeys
data = rand(Int8, 2,10,3) .|> abs;
A = KeyedArray(data; channel = [:left, :right],
                     time = range(13, step = 2.5, length = 10),
                     iter = 31:33)

One can index as A[iter=1] or lookup as A(iter=31). I really want to index as A[iter=31], though (I'm not too concerned about performance in this particular case). AxisArrays is also quite clunky for this use case.

Dictionaries.jl is suggested as an alternative to do the kind of indexing I want. I just can't figure out how to do it for multidimensional arrays, though. If it is really possible, does anyone have an example?

view this post on Zulip jar (Mar 16 2023 at 04:28):

I don't think it's possible to do multidimensionality in Dictionaries.jl though there are some discussions in issues about it

view this post on Zulip Alexander (Mar 16 2023 at 11:47):

AIU, when you start indexing by labels instead of sequential integer keys, the thing stops being an abstractarray. So, a dictionary is totally fine as long as you don't need array functionality:

d = dictionary([(channel=:left, time=13, iter=31) => 1, (channel=:right, time=13, iter=31) => 2, ...])
d[(channel=:left, time=13, iter=31)]  == 1

But when array functionality is needed (eg slicing), it's probably better to stay within the realm of actual arrays. This means, indexing goes by sequential indices.
Why AxisKeys' label lookup with round brackets instead of square brackets doesn't work for your usecase?

view this post on Zulip mbaz (Mar 16 2023 at 12:58):

Alexander said:

But when array functionality is needed (eg slicing), it's probably better to stay within the realm of actual arrays. This means, indexing goes by sequential indices.

It can be done, but it's slow. In my particular use case, I'd rather have convenience than speed, though.

Why AxisKeys' label lookup with round brackets instead of square brackets doesn't work for your usecase?

The reason is that lookup doesn't work for assignment. I'd like to be able to do A[iter=31] = ....

view this post on Zulip mbaz (Mar 16 2023 at 14:24):

I had missed NamedArrays.jl, found it in an issue in Dictionaries.jl. It is actually the closest to what I'm looking for.

view this post on Zulip Sundar R (Mar 16 2023 at 18:54):

There's also NamedDims.jl and DimensionalData.jl

view this post on Zulip Alexander (Mar 16 2023 at 18:59):

The reason is that lookup doesn't work for assignment. I'd like to be able to do A[iter=31] = ....

Setting the whole slice:

A(channel=:left, iter=32) .= -1

Setting a single value:

# note the trailing colon
julia> A(:left, 18, 32, :) .= -1

Unfortunately, specifying dims by names doesn't work in the latter case. This isn't fundamental though, see https://github.com/mcabbott/AxisKeys.jl/pull/110 (and upvote it :) ).

view this post on Zulip mbaz (Mar 16 2023 at 19:06):

Upvoted

view this post on Zulip mbaz (Mar 16 2023 at 23:25):

I'm implementing my own solution, just for fun... so far I got this:

julia> using CatalogArrays

julia> a = rand(2, 3)
2×3 Matrix{Float64}:
 0.456233  0.322689  0.501975
 0.943775  0.160793  0.482612

julia> b = CatalogArray(a, snr = (10, 20), n = (.2, .4, .6));
julia> b[2, 2]
0.16079269059283696

julia> b[snr = 20, n = 0.4]
0.16079269059283696

julia> b[n = 0.4, snr = 20]
0.16079269059283696

Now I just need to implement slicing and setindex! :stuck_out_tongue:


Last updated: Oct 02 2023 at 04:34 UTC