@@ -61,8 +61,12 @@ Base.getindex(A::Axis, i...) = A.val[i...]
61
61
Base. unsafe_getindex (A:: Axis , i... ) = Base. unsafe_getindex (A, i... )
62
62
Base. eltype {_,T} (:: Type{Axis{_,T}} ) = eltype (T)
63
63
Base. size (A:: Axis ) = size (A. val)
64
+ Base. indices (A:: Axis ) = indices (A. val)
65
+ Base. indices (A:: Axis , d) = indices (A. val, d)
64
66
Base. length (A:: Axis ) = length (A. val)
65
67
@compat (A:: Axis{name} ){name}(i) = Axis {name} (i)
68
+ Base. convert {name,T} (:: Type{Axis{name,T}} , ax:: Axis{name,T} ) = ax
69
+ Base. convert {name,T} (:: Type{Axis{name,T}} , ax:: Axis{name} ) = Axis {name} (convert (T, ax. val))
66
70
67
71
@doc """
68
72
An AxisArray is an AbstractArray that wraps another AbstractArray and
@@ -95,11 +99,12 @@ AxisArray(A::AbstractArray, vectors::AbstractVector...)
95
99
* `A::AbstractArray` : the wrapped array data
96
100
* `axes` or `names` or `vectors` : dimensional information for the wrapped array
97
101
98
- The dimensional information may be passed in one of three ways and is entirely
99
- optional. When the axis name or value is missing for a dimension, a default is
100
- substituted. The default axis names for dimensions `(1, 2, 3, 4, 5, ...)` are
101
- `(:row, :col, :page, :dim_4, :dim_5, ...)`. The default axis values are the
102
- integer unit ranges: `1:size(A, d)` for each missing dimension `d`.
102
+ The dimensional information may be passed in one of three ways and is
103
+ entirely optional. When the axis name or value is missing for a
104
+ dimension, a default is substituted. The default axis names for
105
+ dimensions `(1, 2, 3, 4, 5, ...)` are `(:row, :col, :page, :dim_4,
106
+ :dim_5, ...)`. The default axis values are `indices(A, d)` for each
107
+ missing dimension `d`.
103
108
104
109
### Indexing
105
110
@@ -166,12 +171,12 @@ AxisArray(A::AbstractArray, axs::Axis...) = AxisArray(A, axs)
166
171
push! (ax. args, :(axs[$ i]))
167
172
end
168
173
for i= L+ 1 : N
169
- push! (ax. args, :(Axis {_defaultdimname($i)} (1 : size (A, $ i))))
174
+ push! (ax. args, :(Axis {_defaultdimname($i)} (indices (A, $ i))))
170
175
end
171
176
quote
172
177
for i = 1 : length (axs)
173
178
checkaxis (axs[i]. val)
174
- if length (axs[i]. val) != size (A, i)
179
+ if _length (axs[i]. val) != _size (A, i)
175
180
throw (ArgumentError (" the length of each axis must match the corresponding size of data" ))
176
181
end
177
182
end
@@ -183,7 +188,7 @@ AxisArray(A::AbstractArray, axs::Axis...) = AxisArray(A, axs)
183
188
end
184
189
# Simple non-type-stable constructors to specify just the name or axis values
185
190
AxisArray (A:: AbstractArray ) = AxisArray (A, ()) # Disambiguation
186
- AxisArray (A:: AbstractArray , names:: Symbol... ) = AxisArray (A, ntuple (i -> Axis {names[i]} ( 1 : size (A, i)), length (names )))
191
+ AxisArray (A:: AbstractArray , names:: Symbol... ) = AxisArray (A, map ((name,ind) -> Axis {name} (ind), names, indices (A )))
187
192
AxisArray (A:: AbstractArray , vects:: AbstractVector... ) = AxisArray (A, ntuple (i-> Axis {_defaultdimname(i)} (vects[i]), length (vects)))
188
193
189
194
# Axis definitions
214
219
Base. size (A:: AxisArray ) = size (A. data)
215
220
Base. size (A:: AxisArray , Ax:: Axis ) = size (A. data, axisdim (A, Ax))
216
221
Base. size {Ax<:Axis} (A:: AxisArray , :: Type{Ax} ) = size (A. data, axisdim (A, Ax))
222
+ Base. indices (A:: AxisArray ) = indices (A. data)
223
+ Base. indices (A:: AxisArray , Ax:: Axis ) = indices (A. data, axisdim (A, Ax))
224
+ Base. indices {Ax<:Axis} (A:: AxisArray , :: Type{Ax} ) = indices (A. data, axisdim (A, Ax))
217
225
Base. linearindexing (A:: AxisArray ) = Base. linearindexing (A. data)
218
226
Base. convert {T,N} (:: Type{Array{T,N}} , A:: AxisArray{T,N} ) = convert (Array{T,N}, A. data)
219
227
# Similar is tricky. If we're just changing the element type, it can stay as an
@@ -233,25 +241,25 @@ Base.similar{T}(A::AxisArray{T}, S::Type, dims::Tuple{Vararg{Int}}) = similar(A.
233
241
Base. similar {T} (A:: AxisArray{T} , axs:: Axis... ) = similar (A, T, axs)
234
242
Base. similar {T} (A:: AxisArray{T} , S:: Type , axs:: Axis... ) = similar (A, S, axs)
235
243
@generated function Base. similar {T,N} (A:: AxisArray{T,N} , S:: Type , axs:: Tuple{Vararg{Axis}} )
236
- sz = Expr (:tuple )
244
+ inds = Expr (:tuple )
237
245
ax = Expr (:tuple )
238
246
for d= 1 : N
239
- push! (sz . args, :(size (A, Axis{$ d})))
247
+ push! (inds . args, :(indices (A, Axis{$ d})))
240
248
push! (ax. args, :(axes (A, Axis{$ d})))
241
249
end
242
250
to_delete = Int[]
243
251
for i= 1 : length (axs. parameters)
244
252
a = axs. parameters[i]
245
253
d = axisdim (A, a)
246
254
axistype (a) <: Tuple{} && push! (to_delete, d)
247
- sz . args[d] = :(length (axs[$ i]. val))
255
+ inds . args[d] = :(indices (axs[$ i]. val, 1 ))
248
256
ax. args[d] = :(axs[$ i])
249
257
end
250
258
sort! (to_delete)
251
- deleteat! (sz . args, to_delete)
259
+ deleteat! (inds . args, to_delete)
252
260
deleteat! (ax. args, to_delete)
253
261
quote
254
- d = similar (A. data, S, $ sz )
262
+ d = similar (A. data, S, $ inds )
255
263
AxisArray (d, $ ax)
256
264
end
257
265
end
@@ -356,3 +364,10 @@ function checkaxis(::Type{Categorical}, ax)
356
364
push! (seen, elt)
357
365
end
358
366
end
367
+
368
+ _length (A:: AbstractArray ) = length (linearindices (A))
369
+ _length (A) = length (A)
370
+ _size (A:: AbstractArray ) = map (length, indices (A))
371
+ _size (A) = size (A)
372
+ _size (A:: AbstractArray , d) = length (indices (A, d))
373
+ _size (A, d) = size (A, d)
0 commit comments