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.
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.
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]])]
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]])
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.
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.
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]])]
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]])