Selectors
In addition to choosing dimensions by name, we can also select values within them.
First, we can create a DimArray
with lookup values as well as dimension names:
using DimensionalData
julia> A = rand(X(1.0:0.2:2.0), Y([:a, :b, :c]))
╭──────────────────────────╮
│ 6×3 DimArray{Float64, 2} │
├──────────────────────────┴───────────────────────────────────────────── dims ┐
↓ X Sampled{Float64} 1.0:0.2:2.0 ForwardOrdered Regular Points,
→ Y Categorical{Symbol} [:a, :b, :c] ForwardOrdered
└──────────────────────────────────────────────────────────────────────────────┘
↓ → :a :b :c
1.0 0.27736 0.802776 0.621603
1.2 0.444305 0.156538 0.768488
1.4 0.184738 0.226064 0.869012
1.6 0.772277 0.764895 0.101231
1.8 0.711133 0.86273 0.239921
2.0 0.883222 0.748041 0.511313
Then we can use the Selector
to select values from the array:
The At(x)
selector gets the index or indices exactly matching the passed in value(s).
julia> A[X=At(1.2), Y=At(:c)]
0.7684883626668314
Or within a tolerance:
julia> A[X=At(0.99:0.201:1.5; atol=0.05)]
╭──────────────────────────╮
│ 3×3 DimArray{Float64, 2} │
├──────────────────────────┴───────────────────────────────────────────── dims ┐
↓ X Sampled{Float64} [1.0, 1.2, 1.4] ForwardOrdered Irregular Points,
→ Y Categorical{Symbol} [:a, :b, :c] ForwardOrdered
└──────────────────────────────────────────────────────────────────────────────┘
↓ → :a :b :c
1.0 0.27736 0.802776 0.621603
1.2 0.444305 0.156538 0.768488
1.4 0.184738 0.226064 0.869012
At
can also take vectors and ranges:
julia> A[X=At(1.2:0.2:1.5), Y=At([:a, :c])]
╭──────────────────────────╮
│ 2×2 DimArray{Float64, 2} │
├──────────────────────────┴───────────────────────────────────────────── dims ┐
↓ X Sampled{Float64} [1.2, 1.4] ForwardOrdered Irregular Points,
→ Y Categorical{Symbol} [:a, :c] ForwardOrdered
└──────────────────────────────────────────────────────────────────────────────┘
↓ → :a :c
1.2 0.444305 0.768488
1.4 0.184738 0.869012
Lookups
Selectors find indices in the Lookup
of each dimension. Lookups wrap other AbstractArray
(often AbstractRange
) but add additional traits to facilitate fast lookups or specifying point or interval behaviour. These are usually detected automatically.
using DimensionalData.Lookups
The Sampled(x)
lookup holds values sampled along an axis. They may be Ordered
/Unordered
, Intervals
/Points
, and Regular
/Irregular
.
Most of these properties are usually detected automatically, but here we create a Sampled
lookup manually:
julia> l = Sampled(10.0:10.0:100.0; order=ForwardOrdered(), span=Regular(10.0), sampling=Intervals(Start()))
Sampled{Float64} ForwardOrdered Regular Intervals{Start}
wrapping: 10.0:10.0:100.0
To specify Irregular
Intervals
, we should include the outer bounds of the lookup, as we can't determine them from the vector.
julia> l = Sampled([13, 8, 5, 3, 2, 1]; order=ForwardOrdered(), span=Irregular(1, 21), sampling=Intervals(Start()))
Sampled{Int64} ForwardOrdered Irregular Intervals{Start}
wrapping: 6-element Vector{Int64}:
13
8
5
3
2
1
Lookup autodetection
When we define an array, extra properties are detected:
julia> A = DimArray(rand(7, 5), (X(10:10:70), Y([:a, :b, :c, :d, :e])))
╭──────────────────────────╮
│ 7×5 DimArray{Float64, 2} │
├──────────────────────────┴───────────────────────────────────────────── dims ┐
↓ X Sampled{Int64} 10:10:70 ForwardOrdered Regular Points,
→ Y Categorical{Symbol} [:a, :b, :c, :d, :e] ForwardOrdered
└──────────────────────────────────────────────────────────────────────────────┘
↓ → :a :b :c :d :e
10 0.71372 0.301659 0.229418 0.442111 0.680987
20 0.905616 0.307762 0.228248 0.882656 0.396585
30 0.0928922 0.651538 0.152068 0.683795 0.687921
40 0.441181 0.314906 0.650675 0.570603 0.647225
50 0.621662 0.196478 0.97293 0.929034 0.855976
60 0.72217 0.791844 0.883323 0.21921 0.0575993
70 0.896257 0.758149 0.679453 0.506221 0.771237
This array has a Sampled
lookup with ForwardOrdered
Regular
Points
for X
, and a Categorical
ForwardOrdered
for Y
.
Most lookup types and properties are detected automatically like this from the arrays and ranges used.
Arrays and ranges of
String
,Symbol
, andChar
are set toCategorical
lookup.order
is detected asUnordered
,ForwardOrdered
, orReverseOrdered
Arrays and ranges of
Number
,DateTime
, and other things are set toSampled
lookups.order
is detected asUnordered
,ForwardOrdered
, orReverseOrdered
.sampling
is set toPoints()
unless the values areIntervalSets.Interval
, thenIntervals(Center())
is used.span
is detected asRegular(step(range))
forAbstractRange
andIrregular(nothing, nothing)
for otherAbstractArray
, wherenothing, nothing
are the unknown outer bounds of the lookup. They are not needed forPoints
as the outer values are the outer bounds. But they can be specified manually forIntervals
Empty dimensions or dimension types are assigned
NoLookup()
ranges that can't be used with selectors as they hold no values.
DimSelector
We can also index with arrays of selectors DimSelectors
. These are like CartesianIndices
or DimIndices
, but holding the Selectors
At
, Near
, or Contains
.
julia> A = rand(X(1.0:0.2:2.0), Y(10:2:20))
╭──────────────────────────╮
│ 6×6 DimArray{Float64, 2} │
├──────────────────────────┴───────────────────────────────────────────── dims ┐
↓ X Sampled{Float64} 1.0:0.2:2.0 ForwardOrdered Regular Points,
→ Y Sampled{Int64} 10:2:20 ForwardOrdered Regular Points
└──────────────────────────────────────────────────────────────────────────────┘
↓ → 10 12 14 16 18 20
1.0 0.0775482 0.263531 0.361536 0.508614 0.89559 0.564657
1.2 0.838572 0.388768 0.44818 0.0300922 0.595409 0.952489
1.4 0.166221 0.0689895 0.499307 0.228081 0.473944 0.747695
1.6 0.11787 0.143478 0.0831822 0.528009 0.631878 0.993001
1.8 0.0905873 0.909826 0.557418 0.229792 0.29205 0.699118
2.0 0.495624 0.810377 0.120845 0.574678 0.371583 0.460775
We can define another array with partly matching indices
julia> B = rand(X(1.0:0.04:2.0), Y(20:-1:10))
╭────────────────────────────╮
│ 26×11 DimArray{Float64, 2} │
├────────────────────────────┴─────────────────────────────────────────── dims ┐
↓ X Sampled{Float64} 1.0:0.04:2.0 ForwardOrdered Regular Points,
→ Y Sampled{Int64} 20:-1:10 ReverseOrdered Regular Points
└──────────────────────────────────────────────────────────────────────────────┘
↓ → 20 19 … 12 11 10
1.0 0.751498 0.988013 0.966133 0.465112 0.227865
1.04 0.241791 0.34589 0.0773793 0.728852 0.462859
1.08 0.412631 0.0143204 0.454134 0.0417586 0.286
1.12 0.300304 0.660657 0.712342 0.806495 0.727464
⋮ ⋱ ⋮
1.84 0.752331 0.491911 0.221313 0.72454 0.00869054
1.88 0.296393 0.00428189 0.951789 0.142406 0.331422
1.92 0.930699 0.777408 0.0661958 0.0737984 0.539197
1.96 0.744107 0.360032 … 0.0699673 0.264001 0.27206
2.0 0.635373 0.533041 0.574526 0.531012 0.503183
And we can simply select values from B
with selectors from A
:
julia> B[DimSelectors(A)]
╭──────────────────────────╮
│ 6×6 DimArray{Float64, 2} │
├──────────────────────────┴───────────────────────────────────────────── dims ┐
↓ X Sampled{Float64} [1.0, 1.2, …, 1.8, 2.0] ForwardOrdered Irregular Points,
→ Y Sampled{Int64} [10, 12, …, 18, 20] ReverseOrdered Irregular Points
└──────────────────────────────────────────────────────────────────────────────┘
↓ → 10 12 14 16 18 20
1.0 0.227865 0.966133 0.40169 0.990114 0.358535 0.751498
1.2 0.235356 0.675459 0.426312 0.768719 0.569347 0.399781
1.4 0.508938 0.166186 0.0811277 0.342499 0.819291 0.998484
1.6 0.573391 0.740107 0.817199 0.690159 0.527254 0.634257
1.8 0.0255364 0.895115 0.519705 0.626382 0.171961 0.6063
2.0 0.503183 0.574526 0.98981 0.450629 0.545522 0.635373
If the lookups aren't aligned, we can use Near
instead of At
, which is like doing a nearest neighbor interpolation:
julia> C = rand(X(1.0:0.007:2.0), Y(10.0:0.9:30))
╭─────────────────────────────╮
│ 143×23 DimArray{Float64, 2} │
├─────────────────────────────┴────────────────────────────────────────── dims ┐
↓ X Sampled{Float64} 1.0:0.007:1.994 ForwardOrdered Regular Points,
→ Y Sampled{Float64} 10.0:0.9:29.8 ForwardOrdered Regular Points
└──────────────────────────────────────────────────────────────────────────────┘
↓ → 10.0 10.9 … 28.0 28.9 29.8
1.0 0.341785 0.946655 0.954153 0.0821229 0.828315
1.007 0.275784 0.22401 0.199364 0.485952 0.193179
1.014 0.659836 0.832345 0.672556 0.0760101 0.950007
1.021 0.168617 0.890377 0.258764 0.195897 0.747615
⋮ ⋱
1.966 0.426134 0.713457 0.693866 0.899783 0.166822
1.973 0.601787 0.904115 … 0.0670244 0.42964 0.639039
1.98 0.902689 0.231483 0.18906 0.670627 0.67989
1.987 0.454047 0.92977 0.493784 0.998661 0.276742
1.994 0.846736 0.0923954 0.00258281 0.273104 0.562491
julia> C[DimSelectors(A; selectors=Near)]
╭──────────────────────────╮
│ 6×6 DimArray{Float64, 2} │
├──────────────────────────┴───────────────────────────────────────────── dims ┐
↓ X Sampled{Float64} [1.0, 1.203, …, 1.798, 1.994] ForwardOrdered Irregular Points,
→ Y Sampled{Float64} [10.0, 11.8, …, 18.1, 19.9] ForwardOrdered Irregular Points
└──────────────────────────────────────────────────────────────────────────────┘
↓ → 10.0 11.8 13.6 16.3 18.1 19.9
1.0 0.341785 0.0506805 0.621422 0.775495 0.198058 0.168554
1.203 0.333095 0.953651 0.943783 0.789816 0.215448 0.106973
1.399 0.641266 0.694096 0.0724261 0.603258 0.994395 0.570396
1.602 0.827349 0.662227 0.682734 0.432028 0.707314 0.0542529
1.798 0.192274 0.243368 0.53407 0.513909 0.0154473 0.450775
1.994 0.846736 0.573469 0.0410007 0.513088 0.221908 0.0135194