【问题标题】:Flatten or group array in blocks of columns - NumPy / Python在列块中展平或分组数组 - NumPy / Python
【发布时间】:2025-12-03 04:50:02
【问题描述】:

有什么简单的方法可以弄平

import numpy    
np.arange(12).reshape(3,4)
Out[]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

进入

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

【问题讨论】:

  • arr.reshape(3, 2, 2).swapaxes(0, 1).ravel() 可以,但如果没有预期的逻辑,很难说它是否是你所追求的......

标签: python numpy flatten


【解决方案1】:

您似乎正在考虑使用特定数量的列来形成块,然后获取每个块中的元素,然后移动到下一个块中。所以,考虑到这一点,这是一种方法 -

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

背后的动机在this post中有详细讨论。

另外,为了保持 2D 格式 -

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

并以 直观 3D 数组格式使用它 -

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】:

    为此,我只需切片和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】:

      另一种方式:

      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】:

        您可以使用列表推导将数组分割成块,然后使用numpy.ndarray.flatten 方法将块展平为一维数组(这仅在a.shape[1] 可被块大小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)
        

        输出:

        [ 0  1  4  5  8  9  2  3  6  7 10 11 ]
        

        【讨论】:

          【解决方案5】:

          如果你愿意,我有一个不涉及 numpy 的解决方案,它会照顾你得到的每一种数组,

          [[12312],[],[[]]] 
          [[[2]], [4, [5, 6, [6], 6, 6, 6], 7]]
          [-1, [1, [-2], 1], -1]
          etc
          

          第一个选项(不适用于字符串

          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
          

          第二个选项:

          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】:

            你在这里使用 numpy。它有一种方法可以完全按照您的意愿行事。

            import numpy as np
            
            arr = np.arange(12).reshape(3,4)
            flat = arr.flatten()
            

            另一种方法:

            a = []
            [a.extend(x) for x in arr]
            

            【讨论】:

            • 您忽略了所需的模式。