Concatenating empty array in Numpy

PythonArraysMatlabNumpy

Python Problem Overview


in Matlab I do this:

>> E = [];
>> A = [1 2 3 4 5; 10 20 30 40 50];
>> E = [E ; A]

E =

     1     2     3     4     5
    10    20    30    40    50

Now I want the same thing in Numpy but I have problems, look at this:

>>> E = array([],dtype=int)
>>> E
array([], dtype=int64)
>>> A = array([[1,2,3,4,5],[10,20,30,40,50]])

>>> E = vstack((E,A))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/core/shape_base.py", line 226, in vstack
    return _nx.concatenate(map(atleast_2d,tup),0)
ValueError: array dimensions must agree except for d_0

I have a similar situation when I do this with:

>>> E = concatenate((E,A),axis=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: arrays must have same number of dimensions

Or:

>>> E = append([E],[A],axis=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/lib/function_base.py", line 3577, in append
    return concatenate((arr, values), axis=axis)
ValueError: arrays must have same number of dimensions

Python Solutions


Solution 1 - Python

if you know the number of columns before hand:

>>> xs = np.array([[1,2,3,4,5],[10,20,30,40,50]])
>>> ys = np.array([], dtype=np.int64).reshape(0,5)
>>> ys
array([], shape=(0, 5), dtype=int64)
>>> np.vstack([ys, xs])
array([[  1.,   2.,   3.,   4.,   5.],
       [ 10.,  20.,  30.,  40.,  50.]])

if not:

>>> ys = np.array([])
>>> ys = np.vstack([ys, xs]) if ys.size else xs
array([[ 1,  2,  3,  4,  5],
       [10, 20, 30, 40, 50]])

Solution 2 - Python

In Python, if possible to work with the individual vectors, to append you should use list.append()

>>> E = []
>>> B = np.array([1,2,3,4,5])
>>> C = np.array([10,20,30,40,50])
>>> E = E.append(B)
>>> E = E.append(C)
[array([1, 2, 3, 4, 5]), array([10, 20, 30, 40, 50])]

and then after all append operations are done, return to np.array thusly

>>> E = np.array(E)
array([[ 1,  2,  3,  4,  5],
   [10, 20, 30, 40, 50]])

Solution 3 - Python

If you wanna do this just because you cannot concatenate an array with an initialized empty array in a loop, then just use a conditional statement, e.g.

if (i == 0): 
   do the first assignment
else:  
   start your contactenate 

Solution 4 - Python

Something that I've build to deal with this sort of problem. It's also deals with list input instead of np.array:

import numpy as np


def cat(tupleOfArrays, axis=0):
    # deals with problems of concating empty arrays
    # also gives better error massages

    # first check that the input is correct
    assert isinstance(tupleOfArrays, tuple), 'first var should be tuple of arrays'

    firstFlag = True
    res = np.array([])

    # run over each element in tuple
    for i in range(len(tupleOfArrays)):
        x = tupleOfArrays[i]
        if len(x) > 0:  # if an empty array\list - skip
            if isinstance(x, list):  # all should be ndarray
                x = np.array(x)
            if x.ndim == 1:  # easier to concat 2d arrays
                x = x.reshape((1, -1))
            if firstFlag:  # for the first non empty array, just swich the empty res array with it
                res = x
                firstFlag = False
            else:  # actual concatination

                # first check that concat dims are good
                if axis == 0:
                    assert res.shape[1] == x.shape[1], "Error concating vertically element index " + str(i) + \
                                                       " with prior elements: given mat shapes are " + \
                                                       str(res.shape) + " & " + str(x.shape)
                else:  # axis == 1:
                    assert res.shape[0] == x.shape[0], "Error concating horizontally element index " + str(i) + \
                                                       " with prior elements: given mat shapes are " + \
                                                       str(res.shape) + " & " + str(x.shape)

                res = np.concatenate((res, x), axis=axis)
    return res


if __name__ == "__main__":
    print(cat((np.array([]), [])))
    print(cat((np.array([1, 2, 3]), np.array([]), [1, 3, 54+1j]), axis=0))
    print(cat((np.array([[1, 2, 3]]).T, np.array([]), np.array([[1, 3, 54+1j]]).T), axis=1))
    print(cat((np.array([[1, 2, 3]]).T, np.array([]), np.array([[3, 54]]).T), axis=1))  # a bad one

Solution 5 - Python

E = np.array([
    
]).reshape(0, 5)
print("E: \n{}\nShape {}\n".format(E, E.shape))

A = np.vstack([
    [1, 2, 3, 4, 5], 
    [10, 20, 30, 40, 50]]
)
print("A:\n{}\nShape {}\n".format(A, A.shape))

C = np.r_[
    E, 
    A
].astype(np.int32)

print("C:\n{}\nShape {}\n".format(C, C.shape))
E: 
[]
Shape (0, 5)

A:
[[ 1  2  3  4  5]
 [10 20 30 40 50]]
Shape (2, 5)

C:
[[ 1  2  3  4  5]
 [10 20 30 40 50]]
Shape (2, 5)

Solution 6 - Python

A solution is to use the None object and np.concatenate, np.hstack or np.vstack.

>>> arr=None
>>> p=np.array([0,1,2,3])

>>> for i in range(0,2):
>>>     arr = (np.vstack((arr, p)) if (arr is not None) else p)

array([[ 0, 1, 2, 3],
      [[ 0, 1, 2, 3]])

Solution 7 - Python

np.concatenate, np.hstack and np.vstack will do what you want. Note however that NumPy arrays are not suitable for use as dynamic arrays. Use Python lists for that purpose instead.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionmaxv15View Question on Stackoverflow
Solution 1 - Pythonbehzad.nouriView Answer on Stackoverflow
Solution 2 - PythonWurmDView Answer on Stackoverflow
Solution 3 - PythonMingView Answer on Stackoverflow
Solution 4 - PythonYoniChechikView Answer on Stackoverflow
Solution 5 - PythonmonView Answer on Stackoverflow
Solution 6 - PythonEmTView Answer on Stackoverflow
Solution 7 - PythonSturla MoldenView Answer on Stackoverflow