numpy python - разрезание строк и столбцов одновременно - PullRequest
0 голосов
/ 30 октября 2019

У меня есть пустая матрица с 130 X 13. Скажем, я хочу выбрать определенный набор строк, удовлетворяющих условию, и подмножество столбцов -

trainx[trainy==label,[0,6]]

Приведенный выше код не работает и выдаетошибка - IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (43,) (2,).

Однако, если я делаю это в 2 шага - сначала подмножество строк, а затем столбцы, это работает. Это что-то странное или нудистское работает таким образом?

temp1 = trainx[trainy==label,:]
temp1 = temp1[:,[0,6]]

Ответы [ 2 ]

0 голосов
/ 30 октября 2019
In [154]: x = np.arange(24).reshape(6,4)                                        
In [155]: mask = np.array([1,0,1,0,1,0],bool)

При двухступенчатом подходе:

In [156]: x[mask]                 # x[mask, :]                                                              
Out[156]: 
array([[ 0,  1,  2,  3],
       [ 8,  9, 10, 11],
       [16, 17, 18, 19]])
In [157]: x[mask][:,[1,3]]                                                      
Out[157]: 
array([[ 1,  3],
       [ 9, 11],
       [17, 19]])

Или два индекса можно объединить с ix_:

In [158]: np.ix_(mask, [1,3])                                                   
Out[158]: 
(array([[0],
        [2],
        [4]]), array([[1, 3]]))
In [159]: x[np.ix_(mask, [1,3])]                                                
Out[159]: 
array([[ 1,  3],
       [ 9, 11],
       [17, 19]])

Обратите внимание, что первый массив в Out[158] is np.nonzero(mask)[0][:,None], ненулевые индексы в векторной форме столбца. Этот индексный массив (3,1) может транслироваться с массивом столбцов (2,) для выбора массива элементов (3,2). Или в вашем примере массив (43,2).

Логическое значение mask нельзя превратить в массив (6,1) и использовать для маскировки x;это сработало бы, только если бы оно было превращено в маску (6,4), соответствующую форме x.

Итак, используйте двухэтапное индексирование или используйте ix_.

0 голосов
/ 30 октября 2019

Вы можете просто объединить в цепочку индексацию как

trainx[trainy==label][:, [0,6]]

Пример выполнения

arr = np.random.rand(130,13)
arr[arr[:,0]>0.5][:, [0,6]]
...