Индексируйте разреженную матрицу SciPy с помощью массива логических значений

Массивы NumPy могут быть проиндексированы с помощью массива логических значений для выбора строк, соответствующих True записям:

>>> X = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> rows = np.array([True,False,True])
>>> X[rows]
array([[1, 2, 3],
       [7, 8, 9]])
>>> X[np.logical_not(rows)]
array([[4, 5, 6]])

Но это кажется невозможным с разреженными матрицами SciPy; индексы принимаются как числовые, поэтому False выбирает строку 0, а True выбирает строку 1. Как я могу получить поведение, подобное NumPy?


person Fred Foo    schedule 20.06.2011    source источник


Ответы (1)


Вы можете использовать np.nonzero (или ndarray.nonzero ) в вашем логическом массиве, чтобы получить соответствующие числовые индексы, а затем используйте их для доступа к разреженной матрице. Поскольку "модное индексирование" разреженных матриц весьма ограничено по сравнению с плотными ndarray, вам нужно распаковать кортеж строк, возвращаемый nonzero, и указать, что вы хотите получить все столбцы с помощью : среза:

>>> rows.nonzero()
(array([0, 2]),)
>>> indices = rows.nonzero()[0]
>>> indices
array([0, 2])
>>> sparse[indices, :]
<2x100 sparse matrix of type '<type 'numpy.float64'>'
        with 6 stored elements in LInked List format>
person Ferdinand Beyer    schedule 20.06.2011
comment
Если вы измените rows.nonzero() на rows.nonzero()[0] в указателе на X, я приму этот ответ. Кажется, он работает даже без :, предложенного на scipy-user. - person Fred Foo; 20.06.2011
comment
Индексирование также работает для кортежей, по крайней мере, для обычных ndarrays. Для многомерного индексирования нельзя использовать nonzero()[0]. - person Ferdinand Beyer; 20.06.2011
comment
Только не с разреженными матрицами SciPy: IndexError: tuple index out of range. - person Fred Foo; 20.06.2011
comment
Хорошо, я немного поиграл с разреженными матрицами и обновил ответ. Кажется, что вам действительно нужен : срез, поскольку в противном случае для rows = (0, 2) вы не получите подматрицу, а только единственный элемент в (0, 2). - person Ferdinand Beyer; 20.06.2011
comment
Также есть numpy.flatnonzero(bools) как альтернатива bools.nonzero()[0]. Есть ли причина, по которой разреженная матрица, такая как csr, которая предназначена для нарезки строк, не может обрабатывать логическую индексацию строк? - person ariddell; 01.09.2012
comment
Использование numpy.where() вместо numpy.nonzero() немного более интуитивно понятно. - person Brecht Machiels; 21.12.2017