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

前端 未结 6 647
醉酒成梦
醉酒成梦 2020-12-04 03:00

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         


        
相关标签:
6条回答
  • 2020-12-04 03:31

    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]]])
    
    0 讨论(0)
  • 2020-12-04 03:31

    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 ]
    
    0 讨论(0)
  • 2020-12-04 03:34

    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]
    
    0 讨论(0)
  • 2020-12-04 03:34

    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
    
    0 讨论(0)
  • 2020-12-04 03:34

    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]
    
    0 讨论(0)
  • 2020-12-04 03:44

    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])
    
    0 讨论(0)
提交回复
热议问题