Is there any easy way to flatten
import numpy
np.arange(12).reshape(3,4)
Out[]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11
It seems like you are looking to consider a specific number of cols to form blocks and then getting the elements in each block and then moving onto the next ones. So, with that in mind, here's one way -
In [148]: a
Out[148]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [149]: ncols = 2 # no. of cols to be considered for each block
In [150]: a.reshape(a.shape[0],-1,ncols).swapaxes(0,1).ravel()
Out[150]: array([ 0, 1, 4, 5, 8, 9, 2, 3, 6, 7, 10, 11])
The motivation behind is discussed in detail in this post.
Additionally, to keep the 2D format -
In [27]: a.reshape(a.shape[0],-1,ncols).swapaxes(0,1).reshape(-1,ncols)
Out[27]:
array([[ 0, 1],
[ 4, 5],
[ 8, 9],
[ 2, 3],
[ 6, 7],
[10, 11]])
And to have it in a intuitive 3D array format -
In [28]: a.reshape(a.shape[0],-1,ncols).swapaxes(0,1)
Out[28]:
array([[[ 0, 1],
[ 4, 5],
[ 8, 9]],
[[ 2, 3],
[ 6, 7],
[10, 11]]])
You can use a list comprehension to slice the array into blocks and then use the numpy.ndarray.flatten method to flatten the blocks into a 1D array (this will only work if a.shape[1]
is divisible by the block size n
):
import numpy as np
a = np.arange(12).reshape(3, 4)
n = 2
res = np.array([a[:, i : i + n] for i in range(0, a.shape[1], n)]).flatten()
print(res)
Output:
[ 0 1 4 5 8 9 2 3 6 7 10 11 ]
Another way:
first_list = [entry[0:2] for entry in a]
second_list = [entry[2:4] for entry in a]
flat_list = [item for sublist in first_list for item in sublist] + [item for sublist in second_list for item in sublist]
flat_list # [0, 1, 4, 5, 8, 9, 2, 3, 6, 7, 10, 11]
I have a solution that doesn't involve numpy if you want, and it will take care for every kind of array you'll get,
[[12312],[],[[]]]
[[[2]], [4, [5, 6, [6], 6, 6, 6], 7]]
[-1, [1, [-2], 1], -1]
etc
First option(won't work for strings)
def flat_list(array):
return list(flatten(array))
def flatten(nested):
try:
for sublist in nested:
for element in flatten(sublist):
yield element
except TypeError:
yield nested
Second option:
def flatten(nested): #in case you got strings and you want to avoide an infinite recursion
try:
# Don't iterate over string-like objects:
try: nested + ''
except TypeError: pass
else: raise TypeError
for sublist in nested:
for element in flatten(sublist):
yield element
except TypeError:
yield nested
You are using numpy here. It has a method to do exactly what you want.
import numpy as np
arr = np.arange(12).reshape(3,4)
flat = arr.flatten()
Another approach:
a = []
[a.extend(x) for x in arr]
For this I'd simply slice and concatenate:
n = a.shape[1]//2
np.concatenate([a[:,:n], a[:,n:]]).ravel()
# array([ 0, 1, 4, 5, 8, 9, 2, 3, 6, 7, 10, 11])