Нахождение ненулевых значений / индексов в Numpy - PullRequest
0 голосов
/ 31 мая 2019

У меня довольно большой массив с формой (12388, 4). Первые два значения являются координатами, а вторые два ключевых значения. Некоторые из них равны нулю. Я хочу отфильтровать массив и найти все индексы, где оба вторых значения не равны нулю. Мой код выглядит так:

slice_index,_ = np.where((slice[:,2:4]!=0))
slice_nonzero_values = slice[slice_index]

Форма полученного массива slice_nonzero_values: (18550,4). Таким образом, должно быть что-то пошло не так, как результирующий массив больше, чем исходный. Глядя на csv, я понял, что np.where возвращает мне один и тот же индекс несколько раз, если slice [:, 2] и slice [:, 3] не равны нулю. Таким образом я попробовал includedenp.unique:

slice_index,_ = np.where((slice[:,2:4]!=0))
slice_index_unique = np.unique(slice_index)
slice_nonzero_values = slice[slice_index_unique]

В результате получается форма (9669, 4). Это выглядит намного лучше. Однако, чтобы быть уверенным, что все в порядке, я сделал этот цикл for:

    test = []
    test_index = []
    for index, i in enumerate(slice):
        if i[2]!=0 or i[3]!=0:
            test.append(i)
            test_index.append(index)
    test = np.array(test)
    test_index = np.array(test_index)

Этот цикл приводит к проверке массива в форме (8881, 4). Теперь я совершенно запутался, какой из двух способов является правильным. Основываясь на логике цикла, тестовый массив должен быть правым. Тем не менее, это всего лишь один фрагмент массива буквально тысяч. Я не могу оставить там петлю. Подводя итог: я хочу фильтровать через массив слайсов и получить все записи, которые имеют ненулевые значения в любом из двух последних столбцов. Другими словами, если оба значения (slice [:, 2] и slice [:, 3]) равны нулю, строка выходит. Если только один из них равен нулю, а другой нет, это нормально.

Вот пример массива слайсов:

   array([[0.01032591, 0. , 0.               , 0.        ],
   [0.03256559, 0.00890732, 5.0000000e+00    , 0.        ],
   [0.0468626 , 0.01543951, 0.               , 0.        ],
   ...,
   [0.13899946, 0.8847985 , 0.               , 0.        ],
   [0.13899946, 0.8847985 , 4.0000000e+00    , 5.3900000e+02],
   [0.13899946, 0.8847985 , 0.               , 0.        ]], dtype=float32)

1 Ответ

1 голос
/ 31 мая 2019

Вот рабочая демонстрация.Создать тестовые данные:

import numpy as np

X = np.random.rand(10,4)
X = np.vstack([X, np.zeros([2,4])])

>>> X
array([[0.09889965, 0.01169015, 0.30886119, 0.40204571],
       [0.67277149, 0.01654403, 0.17710642, 0.54201684],
       # ...
       [0.        , 0.        , 0.        , 0.        ],
       [0.        , 0.        , 0.        , 0.        ]])

Найти векторы, последние два числа которых не равны нулю:

idx = np.where(np.sum(X[:,2:], axis=1) != 0)[0]

# alternatively, use np.any
idx = np.where(np.any(X[:,2:], axis=1))[0]

Получить отфильтрованные векторы:

X_none_zeros = X[idx]

>>> X_none_zeros
array([[0.09889965, 0.01169015, 0.30886119, 0.40204571],
       # ...
       [0.78279739, 0.84191242, 0.31685306, 0.54906034]])

>>> X_none_zeros.shape
(10, 4)

>>> X.shape
(12, 4)

Объяснить:фактические коды всего две строки:

# retrieve last 2 numbers for each vector in X
# and sum each vector horizontally, so you have 
# [s1, s2, s3, ...]
# use the condition to filter indexes
idx = np.where(np.sum(X[:,2:], axis=1) != 0)[0]
# retrieve matched vectors accordingly
X_none_zeros = X[idx]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...