12

I have two arrays A and B of unknown dimensions that I want to concatenate along the Nth dimension. For example:

>>> A = rand(2,2)       # just for illustration, dimensions should be unknown
>>> B = rand(2,2)       # idem
>>> N = 5

>>> C = concatenate((A, B), axis=N)
numpy.core._internal.AxisError: axis 5 is out of bounds for array of dimension 2

>>> C = stack((A, B), axis=N)
numpy.core._internal.AxisError: axis 5 is out of bounds for array of dimension 3

A related question is asked here. Unfortunately, the solutions proposed do not work when the dimensions are unknown and we might have to add several new axis until getting a minimum dimension of N.

What I have done is to extend the shape with 1's up until the Nth dimension and then concatenate:

newshapeA = A.shape + (1,) * (N + 1 - A.ndim)
newshapeB = B.shape + (1,) * (N + 1 - B.ndim)
concatenate((A.reshape(newshapeA), B.reshape(newshapeB)), axis=N)

With this code I should be able to concatenate a (2,2,1,3) array with a (2,2) array along axis 3, for instance.

Are there better ways of achieving this?

ps: updated as suggested the first answer.

Miguel
  • 658
  • 1
  • 6
  • 19

3 Answers3

2

This should work:

def atleast_nd(x, n):
    return np.array(x, ndmin=n, subok=True, copy=False)

np.concatenate((atleast_nd(a, N+1), atleast_nd(b, N+1)), axis=N)
Eric
  • 95,302
  • 53
  • 242
  • 374
  • and here I thought I'd have to do a bunch of hand-rolled reshape logic in order to implement an `atleast_nd` function. This is much nicer. Thanks! – tel Dec 06 '20 at 13:02
1

An alternative, using numpy.expand_dims:

>>> import numpy as np
>>> A = np.random.rand(2,2)
>>> B = np.random.rand(2,2)
>>> N=5


>>> while A.ndim < N:
        A= np.expand_dims(A,x)
>>> while B.ndim < N:
        B= np.expand_dims(B,x)
>>> np.concatenate((A,B),axis=N-1)
Lee
  • 29,398
  • 28
  • 117
  • 170
1

I don't think there's anything wrong with your approach, although you can make your code a little more compact:

newshapeA = A.shape + (1,) * (N + 1 - A.ndim)
Jaime
  • 65,696
  • 17
  • 124
  • 159
  • Thank you! that's much better. Still, what I was looking for is some solution avoiding the explicit construction of new shapes. `vstack` and `dstack` do what I want for 2d and 3d arrays only. – Miguel Oct 29 '13 at 16:09