How do I append numpy arrays along a new axis or dimension without flattening

Question:

If given a list or numpy array of the same dimensions and length defined as

lista = [5,2,5,...]
listb = [5,1,8,...]
listc = [1,7,8,...]
listd = [1,0,5,...]
liste = [1,2,1,...]
listf = [9,1,8,...]

How do I get a multidimensional array with an output where the fist index is grouped and put into a multidimensional array?

resulting_list = [[[5,2,5,...], [5,1,8,...]],
                  [[1,7,8,...], [1,0,5,...], [1,2,1,...]],
                  [[9,1,8,...]]]

My solution to this was a for loop but I have been largely unsuccessful, use of numpy.append, numpy.concatenate, numpy.vstack, etc has been unsuccessful.

here is one of my example solutions, it should be noted that the lists are always initially grouped (but not necessarily ranked as its not needed) with the first index in a single stack in an array.

#Data
lista = np.array([5,2,5])
listb = np.array([5,1,8])
listc = np.array([1,7,8])
listd = np.array([1,0,5])
liste = np.array([1,2,1])
listf = np.array([9,1,8])

list_index = np.vstack((lista, listb, listc, listd, liste, listf))

result_list = lista

for i in range(4):
    if list_index[i][0] == list_index[i+1][0]:
       result_list = np.append(result_list, list_index[i+1], axis=0)
    else:
        result_list = np.append(result_list, list_index[i+1], axis=1)

AxisError: axis 1 is out of bounds for array of dimension 1

Generally I am having issues appending these lists to a new dimensions or along a specific axis.

Asked By: idroid8

||

Answers:

One solution is the following:

>>> lists = [lista, listb, listc, listd, liste, listf]
>>> first_vals = {x[0] for x in lists}    # unique first element values
>>> res = [np.array([x for x in lists if x[0] == v]) for v in first_vals]
>>> res
[array([[1, 7, 8],
        [1, 0, 5],
        [1, 2, 1]]),
 array([[5, 2, 5],
        [5, 1, 8]]),
 array([[9, 1, 8]])]

This gives a list of 2-dimensional arrays grouped by the first element. You can convert the whole thing into an array with dtype=object (since the 2D arrays generally have different shapes), but I really see no point in doing so.

Answered By: xcmkz

Not as concise as the accepted answer, but closer in style to what you were trying to do. Mainly I am collecting rows in lists, rather than using array appends. List append is easier to use, and faster.

In [119]: lista = np.array([5,2,5]) 
     ...: listb = np.array([5,1,8]) 
     ...: listc = np.array([1,7,8]) 
     ...: listd = np.array([1,0,5]) 
     ...: liste = np.array([1,2,1]) 
     ...: listf = np.array([9,1,8]) 
     ...:  
     ...: lists = [lista, listb, listc, listd, liste, listf]  

Collect values in a list of lists:

In [126]: result_list = [] 
     ...: alist = []; first = lists[0][0] 
     ...: for row in lists: 
     ...:     if row[0]==first: 
     ...:         alist.append(row) 
     ...:     else: 
     ...:         result_list.append(alist) 
     ...:         alist = [row]; first = row[0] 
     ...: result_list.append(alist)                                                                    

In [127]: result_list                                                                                  
Out[127]: 
[[array([5, 2, 5]), array([5, 1, 8])],
 [array([1, 7, 8]), array([1, 0, 5]), array([1, 2, 1])],
 [array([9, 1, 8])]]

optionally convert the inner lists to arrays:

In [128]: [np.vstack(x) for x in result_list]                                                          
Out[128]: 
[array([[5, 2, 5],
        [5, 1, 8]]), array([[1, 7, 8],
        [1, 0, 5],
        [1, 2, 1]]), array([[9, 1, 8]])]
Answered By: hpaulj

np.stack() is probably what you’re looking for, which joins a sequence of (numpy) arrays along a new axis.
Here is an example from this NumPy page:
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
np.stack((a, b))
>> array([[1, 2, 3],[4, 5, 6]])

Answered By: Masoud
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.