Caspar Wylie
Caspar Wylie

Reputation: 2843

How can I append a numpy array of N-Length to another array of N-dimensions?

Situation

I assumed this would be easy - but turns out there are a few restrictions. I have an empty array, that at this point, is empty and has unknown dimensions.

mainArray = np.array([])

later on, I want to append arrays to my main array, which are of different lengths.

I have tried

*Please assume all arrays I have attempted to append are the result of np.zeros(n)

I have tried np.append() but this does not maintain the correct dimensions (assumes I want a linear array).

I have tried np.concatenate() however, this error

TypeError: only length-1 arrays can be converted to Python scalars

implies I cannot concatenate to an empty array...?

I have tried np.vstack() but get

ValueError: all the input array dimensions except for the concatenation axis must match exactly

...which implies I cannot have added arrays of different lengths?

Question

How can I append n-length arrays to an empty n-dimensional array?

update

Here is an example of an output:

[[0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0]]

Where length of 3 is a variable

Upvotes: 3

Views: 2816

Answers (2)

hpaulj
hpaulj

Reputation: 231665

Your starting array is not empty (ok, it does have 0 elements), and not of unknown dimensions. It has a well defined shape and number of dimensions (1d).

In [704]: a=np.array([])
In [705]: a.shape
Out[705]: (0,)
In [706]: a.ndim
Out[706]: 1

Some examples on concatenate that work with a

In [708]: np.concatenate((a,a,a,a)).shape
Out[708]: (0,)
In [709]: np.concatenate((a,np.zeros(3))).shape
Out[709]: (3,)

As a general rule, don't start with an 'empty' array and try to append to it repeatedly. That's a list approach, and is not efficient with arrays. And because of the dimensionality issue, might not work.

A correct way of doing a repeated append is something like:

alist = []
for i in range(3):
     alist.append([1,2,3])
np.array(alist)

Are the sublists all the same length or not? In your last example, they differ, and the array version is dtype=object. It is 1d, with pointers to lists else where in memory - i.e. glorified list.

In [710]: np.array([[0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0]])
Out[710]: array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0]], dtype=object)

This is a very different thing from what you'd get by vstack of 3 arrays of the same length.

I think you need more practice with basic array construction, and the meaning of shape and dimensions. The title itself shows some confusion - array of length N array of N-dimensions. Those are very different descriptions.

============

The basic point with concatenate is that a (n1,m) array can be joined with a (n2,m) array to produce a (n1+n2,m) array. Similarly for other dimensions. If one array is 1d (m,) it needs to be expanded to (1,m) to perform this concatenation. vstack does this kind of expansion for you.

This means that a (0,) shape array can be concatenated horizontally with other 1d arrays, but can't participate in a 2d vertical concatenation except with a (n2,0) array. A dimension may have size 0, but this is rarely useful, since it doesn't contain any data.

Upvotes: 4

Aaron
Aaron

Reputation: 11075

One of the key concepts of numpy's ndarray is that it is rectangular: all elements at a given depth have the same length. This allows simple indexing with a tuple of positions in each dimension to be mapped onto a single flat array:

array[x,y,z] #where array.shape = (a,b,c)
#is equivalent to:
array.flat[b*c*x + c*y + z]

This allows very fast and efficient operation in c for many algorithms.

Numpy does technically support what you want to do, but the implementation is basically reverting functionality back to native lists. The way to do it with numpy is to specify the array dtype=object.

;TLDR

Arrays are intended to be created the correct size ahead of time and never change size. The functionality does exist, but it bypasses some of the advantages of using numpy arrays in the first place.

Upvotes: 1

Related Questions