Как сделать <= и> = на разреженных матрицах? - PullRequest
0 голосов
/ 16 мая 2018

Можно ли выполнять операции <= или> = на разреженных матрицах Scipy, чтобы выражение возвращало значение True, если операция истинна для всех соответствующих элементов? Например, a <= b означает, что для всех соответствующих элементов (a, b) в матрицах (A, B) a <= b? Вот пример для рассмотрения: </p>

import numpy as np
from scipy.sparse import csr_matrix

np.random.seed(0)
mat = csr_matrix(np.random.rand(10, 12)>0.7, dtype=int)
print(mat.A)
print()

np.random.seed(1)
matb = csr_matrix(np.random.rand(10, 12)>0.7, dtype=int)
print(matb.A)

Запуск этого дает предупреждение: SparseEfficiencyWarning: Comparing sparse matrices using >= and <= is inefficient, using <, >, or !=, instead и выдает ошибку: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().

Я хотел бы иметь возможность взять 2 разреженных матрицы, A и B, и определить, является ли A <= B для каждой пары соответствующих элементов (a, b) в (A, B). Это возможно? Каким будет выполнение такой операции? </p>

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

(собрав несколько комментариев вместе для этого ответа):

Чтобы просто сделать поэлементно <= для двух разреженных матриц A и B, вы можете сделать (A <= B).Однако, как указывает @hpaulj, это неэффективно, поскольку любая пара соответствующих 0 элементов (т. Е. (1,1) равно 0 как в A, так и в B) будет преобразована в 1 с помощью этой операции.Предполагая, что A и B являются разреженными (в основном 0), вы уничтожите их разреженность, сделав их в основном 1 с. </p>

Чтобы обойти это, рассмотрите следующее:

A = csr_matrix((3, 3))
A[1, 1] = 1
print(A.A)
print()

B = csr_matrix((3, 3))
B[0, 0] = 1
B[1, 1] = 2
print(B.A)

print(not (A > B).count_nonzero())

Чтобы объяснить, чтопоследняя строка, A > B будет делать противоположное A <= B, поэтому соответствующие 0 останутся 0, и любое место, где a > b станет 1. Поэтому, если получающаяся матрица имеет любые ненулевые элементы, это означает, чтов (A, B) есть некоторые (a, b), где a> b.Это означает, что не случай, когда A <= B (поэлементно). </p>

0 голосов
/ 16 мая 2018
In [402]: np.random.seed = 0
     ...: mat = sparse.csr_matrix(np.random.rand(10, 12)>0.7, dtype=int)
In [403]: mat
Out[403]: 
<10x12 sparse matrix of type '<class 'numpy.int64'>'
    with 40 stored elements in Compressed Sparse Row format>
In [404]: mat.A
Out[404]: 
array([[1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0],
       [1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
       ...
       [0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1],
       [0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]], dtype=int64)
In [405]: np.random.seed = 1
     ...: matb = sparse.csr_matrix(np.random.rand(10, 12)>0.7, dtype=int)

In [407]: mat<matb
Out[407]: 
<10x12 sparse matrix of type '<class 'numpy.bool_'>'
    with 27 stored elements in Compressed Sparse Row format>
In [408]: mat>=matb
/home/paul/.local/lib/python3.6/site-packages/scipy/sparse/compressed.py:295: SparseEfficiencyWarning: Comparing sparse matrices using >= and <= is inefficient, using <, >, or !=, instead.
  "using <, >, or !=, instead.", SparseEfficiencyWarning)
Out[408]: 
<10x12 sparse matrix of type '<class 'numpy.float64'>'
    with 93 stored elements in Compressed Sparse Row format>

В вашем случае ни mat, ни matb не являются особенно разреженными, 40 и 36 ненулевых из возможных 120. Даже в этом случае mat<matb дает 27 ненулевых (True) значений, в то время как тест >= результат в 93. Если обе матрицы равны 0, результат равен True.

Это предупреждает нас о том, что использование разреженных матриц не поможет нам сэкономить пространство или время (по сравнению с плотными массивами), если мы проведем такое тестирование. Это не убьет нас, оно просто не будет таким эффективным.

...