Странное поведение NumPy hstack - PullRequest
0 голосов
/ 16 мая 2019

Учитывая небольшой фон здесь.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 должны быть одной и той же матрицей, но в моей машине это не так.Так чего мне здесь не хватает?Заранее спасибо

Ответы [ 3 ]

4 голосов
/ 16 мая 2019

Транспонирование 1-d массивов, таких как arr3 и arr4, возвращает 1-й массив, а не 2-d.

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]])
1 голос
/ 16 мая 2019
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,)

Транспонировать переключает оси, но не добавляет.

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

vstack (вертикальный) проверяет, что входы как минимум 2d, и соединяет их на 1-й оси

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, поэтому оно имеет тот же тип dtype, что и arr2.

hstack гарантирует, что входы имеют хотя бы 1 измерение, и присоединяется к последнему. [источник]

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

Опять же, транспонирование не меняет форму 1d.

Еще одна удобная функция:

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')])
1 голос
/ 16 мая 2019

Ваша проблема даже с 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]])
...