Flatten or group array in blocks of columns - NumPy / Python

这一生的挚爱 提交于 2019-12-18 09:25:33

问题


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

into

array([ 0,  1,  4,  5, 8, 9, 2, 3, 6, 7, 10, 11])

回答1:


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



回答2:


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



回答3:


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]



回答4:


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 ]



回答5:


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



回答6:


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]


来源:https://stackoverflow.com/questions/58101239/flatten-or-group-array-in-blocks-of-columns-numpy-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!