【问题标题】:NumPy hstack's weird behaviorNumPy hstack 的奇怪行为
【发布时间】:2019-05-16 00:32:41
【问题描述】:

这里有一点背景。 Numpy v1.16,Python 3.6.8。

然后我运行以下代码:

import numpy as np

arr1 = np.repeat(True,20)
arr2 = np.repeat(np.arange(5),4)

X = np.vstack((arr1,
               arr2 
               )).T

arr3 = np.repeat(True,20).T
arr4 = np.repeat(np.arange(5),4).T

Y = np.hstack((arr3,
               arr4 
               ))

结果是X.shape为(20,2)(正常),而Y.shape为(40,)不正常。

数学上 X 和 Y 应该是完全相同的矩阵,但在我的机器中它们不是。那么我在这里错过了什么?提前谢谢你

【问题讨论】:

    标签: python arrays numpy multidimensional-array concatenation


    【解决方案1】:

    转置一维数组(例如 arr3arr4)返回一维数组,而不是二维数组。

    np.repeat(True,5)
    # returns:
    array([ True,  True,  True,  True,  True])
    
    np.repeat(True,5).T
    # returns:
    array([ True,  True,  True,  True,  True])
    

    它不会产生新的轴。您需要在转置之前执行此操作。

    要增加轴数,可以使用np.newaxis

    a = np.repeat(True, 5)
    a[:, np.newaxis]
    # returns:
    array([[ True],
           [ True],
           [ True],
           [ True],
           [ True]])
    
    a[:, np.newaxis].T
    # returns:
    array([[ True,  True,  True,  True,  True]])
    

    【讨论】:

      【解决方案2】:

      您的问题是即使使用 T 但您的 arr 是一维 (n,) ,这意味着您不能简单地将 T 使其变为 (n,1) 维度

      如何解决:使用numpy 广播获取 (n,1)

      Y = np.hstack((arr3[:,None],
                     arr4[:,None] 
                     ))
      Y
      Out[14]: 
      array([[1, 0],
             [1, 0],
             [1, 0],
             [1, 0],
             [1, 1],
             [1, 1],
             [1, 1],
             [1, 1],
             [1, 2],
             [1, 2],
             [1, 2],
             [1, 2],
             [1, 3],
             [1, 3],
             [1, 3],
             [1, 3],
             [1, 4],
             [1, 4],
             [1, 4],
             [1, 4]])
      

      【讨论】:

        【解决方案3】:
        In [92]: arr1 = np.repeat(True,10) 
            ...: arr2 = np.repeat(np.arange(5),2)                                                                      
        In [93]: arr1.shape                                                             
        Out[93]: (10,)
        In [94]: arr2.shape                                                             
        Out[94]: (10,)
        

        Transpose 切换轴,但不添加任何轴。

        In [95]: arr1.T.shape                                                           
        Out[95]: (10,)
        

        vstack(垂直)确保输入至少为 2d,并在第一个轴上连接它们

        In [96]: np.vstack((arr1,arr2))                                                 
        Out[96]: 
        array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
               [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]])
        In [97]: _.shape                                                                
        Out[97]: (2, 10)
        

        确实如此:

        In [99]: np.concatenate((arr1.reshape(1,-1),arr2.reshape(1,-1)), axis=0)        
        Out[99]: 
        array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
               [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]])
        

        请注意,布尔值 True 已更改为数字 1,因此它与 arr2 具有相同的 dtype。

        hstack 确保输入至少有 1 个维度,并在最后一个维度加入。 [source]

        In [100]: np.hstack((arr1,arr2))                                                
        Out[100]: array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4])
        In [101]: _.shape                                                               
        Out[101]: (20,)
        

        再次转置不会改变一维形状。

        另一个便利功能:

        In [102]: np.column_stack((arr1,arr2)).shape                                    
        Out[102]: (10, 2)
        

        这使输入变为 2d,并在最后一个轴上连接(查看其代码了解详情)

        另一个方便:

        In [103]: np.stack((arr1,arr2),axis=1).shape                                    
        Out[103]: (10, 2)
        In [104]: np.stack((arr1,arr2),axis=0).shape                                    
        Out[104]: (2, 10)
        

        所有这些只是调整尺寸,然后使用concatenate

        结构化数组

        In [110]: arr = np.zeros((10,), dtype='bool,i')                                 
        In [111]: arr['f0']=arr1                                                        
        In [112]: arr['f1']=arr2                                                        
        In [113]: arr                                                                   
        Out[113]: 
        array([( True, 0), ( True, 0), ( True, 1), ( True, 1), ( True, 2),
               ( True, 2), ( True, 3), ( True, 3), ( True, 4), ( True, 4)],
              dtype=[('f0', '?'), ('f1', '<i4')])
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-11-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-14
          相关资源
          最近更新 更多