Cumbersome array reshaping for broadcasting, unlike numpy

dropdims would only unstable if we supported calling it without a dim tuple — then it’d automatically find the singleton dimensions and remove them. That’s how other languages work, but we don’t support it by default because it’s a trap.


On the original topic, @yha wins the prize — the way to do this is with [CartesianIndex()]. There are really just two key rules of Julia’s indexing semantics that make this work:

  • The returned shape is simply the result of concatenating all the shapes of all the indices together. In this manner, you can add dimensions to the output.
  • CartesianIndex can be used to allow your indices to span 0 or multiple dimensions in the source array. In this manner, you can remove dimensions from the output.

This definition — const newaxis = [CartesianIndex()] — just “falls out” from the combination of these two rules. Note that you can even easily repeat this new dimension with multiple elements of CartesianIndex(). An array of CartesianIndex() is simply one that doesn’t “eat up” any indices in the source array but still adds a dimension of the appropriate size to the output.

julia> A = rand(3,2)
3×2 Array{Float64,2}:
 0.357162  0.0357645
 0.983917  0.567235
 0.977043  0.646179

julia> A[:, [CartesianIndex()], :]
3×1×2 Array{Float64,3}:
[:, :, 1] =
 0.3571615947640512
 0.9839174510416808
 0.9770434812986168

[:, :, 2] =
 0.03576453669078483
 0.5672345489133457
 0.646178699858571

julia> A[:, [CartesianIndex(), CartesianIndex()], :]
3×2×2 Array{Float64,3}:
[:, :, 1] =
 0.357162  0.357162
 0.983917  0.983917
 0.977043  0.977043

[:, :, 2] =
 0.0357645  0.0357645
 0.567235   0.567235
 0.646179   0.646179

You can also do the inverse operation — and do “pointwise” indexing between the two columns by simply broadcasting CartesianIndex. The index provided in this case is just a vector (so it only returns a vector), but it spans both dimensions in the source array (since it has CartesianIndex elements):

julia> A = rand(3,3)
3×3 Array{Float64,2}:
 0.811331  0.0344879  0.545456
 0.13033   0.505987   0.367931
 0.973931  0.634874   0.548208

julia> A[CartesianIndex.(1:3, 1:3)]
3-element Array{Float64,1}:
 0.8113309595290243
 0.5059869766015384
 0.5482079082972307
15 Likes