AxisArrays.Axis
— Type.Type-stable axis-specific indexing and identification with a parametric type.
Type parameters
struct Axis{name,T}
name
: the name of the axis, a SymbolT
: the type of the axis
Constructors
Axis{name}(I)
Arguments
name
: the axis name Symbol or integer dimensionI
: the indexer, any indexing type that the axis supports
Examples
Here is an example with a Dimensional axis representing a time sequence along rows and a Categorical axis of Symbols for column headers.
A = AxisArray(reshape(1:60, 12, 5), .1:.1:1.2, [:a, :b, :c, :d, :e])
A[Axis{:col}(2)] # grabs the second column
A[Axis{:col}(:b)] # Same as above, grabs column :b (the second column)
A[Axis{:row}(2)] # grabs the second row
A[Axis{2}(2:5)] # grabs the second through 5th columns
AxisArrays.AxisArray
— Type.An AxisArray is an AbstractArray that wraps another AbstractArray and adds axis names and values to each array dimension. AxisArrays can be indexed by using the named axes as an alternative to positional indexing by dimension. Other advanced indexing along axis values are also provided.
Type parameters
The AxisArray contains several type parameters:
struct AxisArray{T,N,D,Ax} <: AbstractArray{T,N}
T
: the elemental type of the AbstractArrayN
: the number of dimensionsD
: the type of the wrapped AbstractArrayAx
: the names and types of the axes, as a (specialized) NTuple{N, Axis}
Constructors
AxisArray(A::AbstractArray, axes::Axis...)
AxisArray(A::AbstractArray, names::Symbol...)
AxisArray(A::AbstractArray, vectors::AbstractVector...)
AxisArray(A::AbstractArray, (names...,), (steps...,), [(offsets...,)])
Arguments
A::AbstractArray
: the wrapped array dataaxes
ornames
orvectors
: dimensional information for the wrapped array
The dimensional information may be passed in one of three ways and is entirely optional. When the axis name or value is missing for a dimension, a default is substituted. The default axis names for dimensions (1, 2, 3, 4, 5, ...)
are (:row, :col, :page, :dim_4, :dim_5, ...)
. The default axis values are Base.axes(A, d)
for each missing dimension d
.
Indexing
Indexing returns a view into the original data. The returned view is a new AxisArray that wraps a SubArray. Indexing should be type stable. Use Axis{axisname}(idx)
to index based on a specific axis. axisname
is a Symbol specifying the axis to index/slice, and idx
is a normal indexing object (Int
, Array{Int,1}
, etc.) or a custom indexing type for that particular type of axis.
Two main types of axes supported by default include:
Categorical axis – These are vectors of labels, normally Symbols or strings. Elements or slices can be indexed by elements or vectors of elements.
Dimensional axis – These are sorted vectors or iterators that can be indexed by
ClosedInterval()
. These are commonly used for sequences of times or date-times. For regular sample rates, ranges can be used.
User-defined axis types can be added along with custom indexing behaviors. To add add a custom type as a Categorical or Dimensional axis, add a trait using AxisArrays.axistrait
.
For more advanced indexing, you can define custom methods for AxisArrays.axisindexes
.
Examples
Here is an example with a Dimensional axis representing a time sequence along rows (it's a FloatRange) and a Categorical axis of Symbols for column headers.
A = AxisArray(reshape(1:15, 5, 3), Axis{:time}(.1:.1:0.5), Axis{:col}([:a, :b, :c]))
A[Axis{:time}(1:3)] # equivalent to A[1:3,:]
A[Axis{:time}(ClosedInterval(.2,.4))] # restrict the AxisArray along the time axis
A[ClosedInterval(0.,.3), [:a, :c]] # select an interval and two columns
AxisArrays.SortedVector
— Type.A SortedVector is an AbstractVector where the underlying data is ordered (monotonically increasing).
Indexing that would unsort the data is prohibited. A SortedVector is a Dimensional axis, and no checking is done to ensure that the data is sorted. Duplicate values are allowed.
A SortedVector axis can be indexed with an ClosedInterval, with a value, or with a vector of values. Use of a SortedVector{Tuple} axis allows indexing similar to the hierarchical index of the Python Pandas package or the R data.table package.
Constructors
SortedVector(x::AbstractVector)
Keyword Arguments
x::AbstractVector
: the wrapped vector
Examples
v = SortedVector(collect([1.; 10.; 10:15.]))
A = AxisArray(reshape(1:16, 8, 2), v, [:a, :b])
A[ClosedInterval(8.,12.), :]
A[1., :]
A[10., :]
## Hierarchical index example with three key levels
data = reshape(1.:40., 20, 2)
v = collect(zip([:a, :b, :c][rand(1:3,20)], [:x,:y][rand(1:2,20)], [:x,:y][rand(1:2,20)]))
idx = sortperm(v)
A = AxisArray(data[idx,:], SortedVector(v[idx]), [:a, :b])
A[:b, :]
A[[:a,:c], :]
A[(:a,:x), :]
A[(:a,:x,:x), :]
A[ClosedInterval(:a,:b), :]
A[ClosedInterval((:a,:x),(:b,:x)), :]
AxisArrays.axes
— Method.axes(A::AxisArray) -> (Axis...)
axes(A::AxisArray, ax::Axis) -> Axis
axes(A::AxisArray, dim::Int) -> Axis
Returns the tuple of axis vectors for an AxisArray. If an specific Axis
is specified, then only that axis vector is returned. Note that when extracting a single axis vector, axes(A, Axis{1})
) is type-stable and will perform better than axes(A)[1]
.
For an AbstractArray without Axis
information, axes
returns the default axes, i.e., those that would be produced by AxisArray(A)
.
AxisArrays.axisdim
— Method.axisdim(::AxisArray, ::Axis) -> Int
axisdim(::AxisArray, ::Type{Axis}) -> Int
Given an AxisArray and an Axis, return the integer dimension of the Axis within the array.
AxisArrays.axisnames
— Method.axisnames(A::AxisArray) -> (Symbol...)
axisnames(::Type{AxisArray{...}}) -> (Symbol...)
axisnames(ax::Axis...) -> (Symbol...)
axisnames(::Type{Axis{...}}...) -> (Symbol...)
Returns the axis names of an AxisArray or list of Axises as a tuple of Symbols.
AxisArrays.axisvalues
— Method.axisvalues(A::AxisArray) -> (AbstractVector...)
axisvalues(ax::Axis...) -> (AbstractVector...)
Returns the axis values of an AxisArray or list of Axises as a tuple of vectors.
AxisArrays.collapse
— Method.collapse(::Val{N}, As::AxisArray...) -> AxisArray
collapse(::Val{N}, labels::Tuple, As::AxisArray...) -> AxisArray
collapse(::Val{N}, ::Type{NewArrayType}, As::AxisArray...) -> AxisArray
collapse(::Val{N}, ::Type{NewArrayType}, labels::Tuple, As::AxisArray...) -> AxisArray
Collapses AxisArray
s with N
equal leading axes into a single AxisArray
. All additional axes in any of the arrays are collapsed into a single additional axis of type Axis{:collapsed, CategoricalVector{Tuple}}
.
Arguments
::Val{N}
: the greatest common dimension to share between all input arrays. The remaining axes are collapsed. AllN
axes must be common to each input array, at the same dimension. Values from0
up to the minimum number of dimensions across all input arrays are allowed.labels::Tuple
: (optional) an index for each array inAs
used as the leading element in the index tuples in the:collapsed
axis. Defaults to1:length(As)
.::Type{NewArrayType<:AbstractArray{_, N+1}}
: (optional) the desired underlying array type for the returnedAxisArray
.As::AxisArray...
:AxisArray
s to be collapsed together.
Examples
julia> price_data = AxisArray(rand(10), Axis{:time}(Date(2016,01,01):Day(1):Date(2016,01,10)))
1-dimensional AxisArray{Float64,1,...} with axes:
:time, 2016-01-01:1 day:2016-01-10
And data, a 10-element Array{Float64,1}:
0.885014
0.418562
0.609344
0.72221
0.43656
0.840304
0.455337
0.65954
0.393801
0.260207
julia> size_data = AxisArray(rand(10,2), Axis{:time}(Date(2016,01,01):Day(1):Date(2016,01,10)), Axis{:measure}([:area, :volume]))
2-dimensional AxisArray{Float64,2,...} with axes:
:time, 2016-01-01:1 day:2016-01-10
:measure, Symbol[:area, :volume]
And data, a 10×2 Array{Float64,2}:
0.159434 0.456992
0.344521 0.374623
0.522077 0.313256
0.994697 0.320953
0.95104 0.900526
0.921854 0.729311
0.000922581 0.148822
0.449128 0.761714
0.650277 0.135061
0.688773 0.513845
julia> collapsed = collapse(Val(1), (:price, :size), price_data, size_data)
2-dimensional AxisArray{Float64,2,...} with axes:
:time, 2016-01-01:1 day:2016-01-10
:collapsed, Tuple{Symbol,Vararg{Symbol,N} where N}[(:price,), (:size, :area), (:size, :volume)]
And data, a 10×3 Array{Float64,2}:
0.885014 0.159434 0.456992
0.418562 0.344521 0.374623
0.609344 0.522077 0.313256
0.72221 0.994697 0.320953
0.43656 0.95104 0.900526
0.840304 0.921854 0.729311
0.455337 0.000922581 0.148822
0.65954 0.449128 0.761714
0.393801 0.650277 0.135061
0.260207 0.688773 0.513845
julia> collapsed[Axis{:collapsed}(:size)] == size_data
true
AxisArrays.CategoricalVector
— Type.A CategoricalVector is an AbstractVector which is treated as a categorical axis regardless of the element type. Duplicate values are not allowed but are not filtered out.
A CategoricalVector axis can be indexed with an ClosedInterval, with a value, or with a vector of values. Use of a CategoricalVector{Tuple} axis allows indexing similar to the hierarchical index of the Python Pandas package or the R data.table package.
In general, indexing into a CategoricalVector will be much slower than the corresponding SortedVector or another sorted axis type, as linear search is required.
Constructors
CategoricalVector(x::AbstractVector)
Arguments
x::AbstractVector
: the wrapped vector
Examples
v = CategoricalVector(collect([1; 8; 10:15]))
A = AxisArray(reshape(1:16, 8, 2), v, [:a, :b])
A[Axis{:row}(1), :]
A[Axis{:row}(10), :]
A[Axis{:row}([1, 10]), :]
## Hierarchical index example with three key levels
data = reshape(1.:40., 20, 2)
v = collect(zip([:a, :b, :c][rand(1:3,20)], [:x,:y][rand(1:2,20)], [:x,:y][rand(1:2,20)]))
A = AxisArray(data, CategoricalVector(v), [:a, :b])
A[:b, :]
A[[:a,:c], :]
A[(:a,:x), :]
A[(:a,:x,:x), :]
AxisArrays.axisindexes
— Method.axisindexes(ax::Axis, axis_idx) -> array_idx
axisindexes(::Type{<:AxisTrait}, axis_values, axis_idx) -> array_idx
Translate an index into an axis into an index into the underlying array. Users can add additional indexing behaviours for custom axes or custom indices by adding methods to this function.
Examples
Add a method for indexing into an Axis{name, SortedSet}
:
AxisArrays.axisindexes(::Type{Categorical}, ax::SortedSet, idx::AbstractVector) = findin(collect(ax), idx)
Add a method for indexing into a Categorical
axis with a SortedSet
:
AxisArrays.axisindexes(::Type{Categorical}, ax::AbstractVector, idx::SortedSet) = findin(ax, idx)
AxisArrays.axisparams
— Method.axisparams(::AxisArray) -> Vararg{::Type{Axis}}
axisparams(::Type{AxisArray}) -> Vararg{::Type{Axis}}
Returns the axis parameters for an AxisArray.
AxisArrays.axistrait
— Method.axistrait(ax::Axis) -> Type{<:AxisTrait}
axistrait{T}(::Type{T}) -> Type{<:AxisTrait}
Returns the indexing type of an Axis
, any subtype of AxisTrait
. The default is Unsupported
, meaning there is no special indexing behaviour for this axis and indexes into this axis are passed directly to the underlying array.
Two main types of axes supported by default are Categorical
and Dimensional
; see Indexing for more information on these types.
User-defined axis types can be added along with custom indexing behaviors by defining new methods of this function. Here is the example of adding a custom Dimensional axis:
AxisArrays.axistrait(::Type{MyCustomAxis}) = AxisArrays.Dimensional
AxisArrays.default_axes
— Function.default_axes(A::AbstractArray)
default_axes(A::AbstractArray, axs)
Return a tuple of Axis objects that appropriately index into the array A.
The optional second argument can take a tuple of vectors or axes, which will be wrapped with the appropriate axis name.
AxisArrays.permutation
— Method.permutation(to, from) -> p
Calculate the permutation of labels in from
to produce the order in to
. Any entries in to
that are missing in from
will receive an index of 0. Any entries in from
that are missing in to
will have their indices appended to the end of the permutation. Consequently, the length of p
is equal to the longer of to
and from
.
AxisArrays.reaxis
— Method.reaxis(A::AxisArray, I...)
This internal function determines the new set of axes that are constructed upon indexing with I.
AxisArrays.searchsortednearest
— Method.searchsortednearest(vec::AbstractVector, x)
Like searchsortedfirst
or searchsortedlast
, this returns the the index of the element in the sorted vector vec
whose value is closest to x
, rounding up. If there are multiple elements that are equally close to x
, this will return the first index if x
is less than or equal to those in the vector or the last index if x
is greater.
Base.join
— Method.join(As::AxisArray...)
Combines AxisArrays with matching axis names into a single AxisArray. Unlike merge
, the inputs are joined along a newly created axis (optionally specified with the newaxis
keyword argument). The method
keyword argument can be used to specify the join type:
:inner
- keep only those array values at axis values common to all AxisArrays to be joined :left
- keep only those array values at axis values present in the first AxisArray passed :right
- keep only those array values at axis values present in the last AxisArray passed :outer
(default) - keep all array values: create an AxisArray spanning all of the input axis values
If an array value in the output array is not defined in any of the input arrays (i.e. in the case of a left, right, or outer join), it takes the value of the optional fillvalue
keyword argument (default zero).
Base.merge
— Method.merge(As::AxisArray...)
Combines AxisArrays with matching axis names into a single AxisArray spanning all of the axis values of the inputs. If a coordinate is defined in more than ones of the inputs, it takes its value from last input in which it appears. If a coordinate in the output array is not defined in any of the input arrays, it takes the value of the optional fillvalue
keyword argument (default zero).