【问题标题】:Concatenating empty array in Numpy在 Numpy 中连接空数组
【发布时间】:2014-05-09 01:56:52
【问题描述】:

在 Matlab 中我这样做:

>> E = [];
>> A = [1 2 3 4 5; 10 20 30 40 50];
>> E = [E ; A]

E =

     1     2     3     4     5
    10    20    30    40    50

现在我想在 Numpy 中做同样的事情,但我有问题,看看这个:

>>> E = array([],dtype=int)
>>> E
array([], dtype=int64)
>>> A = array([[1,2,3,4,5],[10,20,30,40,50]])

>>> E = vstack((E,A))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/core/shape_base.py", line 226, in vstack
    return _nx.concatenate(map(atleast_2d,tup),0)
ValueError: array dimensions must agree except for d_0

当我这样做时,我遇到了类似的情况:

>>> E = concatenate((E,A),axis=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: arrays must have same number of dimensions

或者:

>>> E = append([E],[A],axis=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/lib/function_base.py", line 3577, in append
    return concatenate((arr, values), axis=axis)
ValueError: arrays must have same number of dimensions

【问题讨论】:

  • 在 MATLAB 中,数组总是二维或更大的。在 numpy 中,它们可以有 1 个甚至 0 个维度。

标签: python arrays matlab numpy


【解决方案1】:

如果您事先知道列数:

>>> xs = np.array([[1,2,3,4,5],[10,20,30,40,50]])
>>> ys = np.array([], dtype=np.int64).reshape(0,5)
>>> ys
array([], shape=(0, 5), dtype=int64)
>>> np.vstack([ys, xs])
array([[  1.,   2.,   3.,   4.,   5.],
       [ 10.,  20.,  30.,  40.,  50.]])

如果没有:

>>> ys = np.array([])
>>> ys = np.vstack([ys, xs]) if ys.size else xs
array([[ 1,  2,  3,  4,  5],
       [10, 20, 30, 40, 50]])

【讨论】:

  • 我不明白第二个实现是如何工作的。看起来 ys.size 应该评估为 False,然后语句就是 ys=xs。
  • @NirvedhMeshram 第二条语句说如果ys.size是一个值,任何不为零或False的值,然后执行该语句。
  • @NirvedhMeshram 我认为你是对的。从逻辑上讲,第二个实现不需要第一个语句。它可以检查ys 是否已经存在:ys = np.vstack([ys, xs]) if 'ys' in vars() else xs
  • 另外,我觉得vstack可以换成concatenate(对应()的使用);有人不这么认为吗?如果我是对的 - 这种方法的本质是在一个空数组上使用reshape
  • 创建一个 0 元素数组以便您可以vstack 的整个想法是错误的。作为一次性操作,它是无用的,作为重复vstack 的一部分,它是低效的。坚持使用列表追加。不要盲目地模仿 MATLAB。
【解决方案2】:

如果你想这样做只是因为你不能在循环中连接一个数组和一个初始化的空数组,那么只需使用条件语句, 例如

if (i == 0): 
   do the first assignment
else:  
   start your contactenate 

【讨论】:

    【解决方案3】:

    在 Python 中,如果可能使用单独的向量,您应该使用 list.append() 追加添加

    >>> E = []
    >>> B = np.array([1,2,3,4,5])
    >>> C = np.array([10,20,30,40,50])
    >>> E = E.append(B)
    >>> E = E.append(C)
    [array([1, 2, 3, 4, 5]), array([10, 20, 30, 40, 50])]
    

    然后在所有追加操作完成后,就这样返回到np.array

    >>> E = np.array(E)
    array([[ 1,  2,  3,  4,  5],
       [10, 20, 30, 40, 50]])
    

    【讨论】:

      【解决方案4】:

      我为解决此类问题而构建的东西。它还处理list 输入而不是np.array

      import numpy as np
      
      
      def cat(tupleOfArrays, axis=0):
          # deals with problems of concating empty arrays
          # also gives better error massages
      
          # first check that the input is correct
          assert isinstance(tupleOfArrays, tuple), 'first var should be tuple of arrays'
      
          firstFlag = True
          res = np.array([])
      
          # run over each element in tuple
          for i in range(len(tupleOfArrays)):
              x = tupleOfArrays[i]
              if len(x) > 0:  # if an empty array\list - skip
                  if isinstance(x, list):  # all should be ndarray
                      x = np.array(x)
                  if x.ndim == 1:  # easier to concat 2d arrays
                      x = x.reshape((1, -1))
                  if firstFlag:  # for the first non empty array, just swich the empty res array with it
                      res = x
                      firstFlag = False
                  else:  # actual concatination
      
                      # first check that concat dims are good
                      if axis == 0:
                          assert res.shape[1] == x.shape[1], "Error concating vertically element index " + str(i) + \
                                                             " with prior elements: given mat shapes are " + \
                                                             str(res.shape) + " & " + str(x.shape)
                      else:  # axis == 1:
                          assert res.shape[0] == x.shape[0], "Error concating horizontally element index " + str(i) + \
                                                             " with prior elements: given mat shapes are " + \
                                                             str(res.shape) + " & " + str(x.shape)
      
                      res = np.concatenate((res, x), axis=axis)
          return res
      
      
      if __name__ == "__main__":
          print(cat((np.array([]), [])))
          print(cat((np.array([1, 2, 3]), np.array([]), [1, 3, 54+1j]), axis=0))
          print(cat((np.array([[1, 2, 3]]).T, np.array([]), np.array([[1, 3, 54+1j]]).T), axis=1))
          print(cat((np.array([[1, 2, 3]]).T, np.array([]), np.array([[3, 54]]).T), axis=1))  # a bad one
      

      【讨论】:

        【解决方案5】:
        E = np.array([
            
        ]).reshape(0, 5)
        print("E: \n{}\nShape {}\n".format(E, E.shape))
        
        A = np.vstack([
            [1, 2, 3, 4, 5], 
            [10, 20, 30, 40, 50]]
        )
        print("A:\n{}\nShape {}\n".format(A, A.shape))
        
        C = np.r_[
            E, 
            A
        ].astype(np.int32)
        
        print("C:\n{}\nShape {}\n".format(C, C.shape))
        
        E: 
        []
        Shape (0, 5)
        
        A:
        [[ 1  2  3  4  5]
         [10 20 30 40 50]]
        Shape (2, 5)
        
        C:
        [[ 1  2  3  4  5]
         [10 20 30 40 50]]
        Shape (2, 5)
        

        【讨论】:

          【解决方案6】:

          一种解决方案是使用None 对象和np.concatenatenp.hstacknp.vstack

          >>> arr=None
          >>> p=np.array([0,1,2,3])
          
          >>> for i in range(0,2):
          >>>     arr = (np.vstack((arr, p)) if (arr is not None) else p)
          
          array([[ 0, 1, 2, 3],
                [[ 0, 1, 2, 3]])
          

          【讨论】:

            【解决方案7】:

            np.concatenatenp.hstacknp.vstack 会做你想做的事。但是请注意,NumPy 数组不适合用作动态数组。为此,请改用 Python 列表。

            【讨论】:

              猜你喜欢
              • 2021-12-24
              • 2012-07-31
              • 2017-05-27
              • 2021-07-10
              • 2019-09-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多