Scipy seyrek matrisi bir sympy seyrek matrise verimli bir şekilde nasıl dönüştürebilirim?
Aşağıdaki özelliklere sahip bir A matrisim var.
<1047x1047 sparse matrix of type '<class 'numpy.float64'>'
with 888344 stored elements in Compressed Sparse Column format>
A bu içeriğe sahiptir.
array([[ 1.00000000e+00, -5.85786642e-17, -3.97082034e-17, ...,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[ 6.82195979e-17, 1.00000000e+00, -4.11166786e-17, ...,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[-4.98202332e-17, 1.13957868e-17, 1.00000000e+00, ...,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
...,
[ 4.56847824e-15, 1.32261454e-14, -7.22890998e-15, ...,
1.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[-9.11597396e-15, -2.28796167e-14, 1.26624823e-14, ...,
0.00000000e+00, 1.00000000e+00, 0.00000000e+00],
[ 1.80765584e-14, 1.93779820e-14, -1.36520100e-14, ...,
0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])
Şimdi bu scipy seyrek matristen bir sympy seyrek matris yaratmaya çalışıyorum .
from sympy.matrices import SparseMatrix
A = SparseMatrix(A)
Ama bu hata mesajını alıyorum.
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().
Kafam karıştı çünkü bu matrisin mantıksal girişi yok.
Herhangi bir yardım için teşekkürler!
Yanıtlar
Hata
Anlamadığınız bir hata aldığınızda, geri dönüşe bakmak için biraz zaman ayırın. Ya da en azından bize gösterin!
In [288]: M = sparse.random(5,5,.2, 'csr')
In [289]: M
Out[289]:
<5x5 sparse matrix of type '<class 'numpy.float64'>'
with 5 stored elements in Compressed Sparse Row format>
In [290]: print(M)
(1, 1) 0.17737340878962138
(2, 2) 0.12362174819457106
(2, 3) 0.24324155883057885
(3, 0) 0.7666429046432961
(3, 4) 0.21848551209470246
In [291]: SparseMatrix(M)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-291-cca56ea35868> in <module>
----> 1 SparseMatrix(M)
/usr/local/lib/python3.6/dist-packages/sympy/matrices/sparse.py in __new__(cls, *args, **kwargs)
206 else:
207 # handle full matrix forms with _handle_creation_inputs
--> 208 r, c, _list = Matrix._handle_creation_inputs(*args)
209 self.rows = r
210 self.cols = c
/usr/local/lib/python3.6/dist-packages/sympy/matrices/matrices.py in _handle_creation_inputs(cls, *args, **kwargs)
1070 if 0 in row.shape:
1071 continue
-> 1072 elif not row:
1073 continue
1074
/usr/local/lib/python3.6/dist-packages/scipy/sparse/base.py in __bool__(self)
281 return self.nnz != 0
282 else:
--> 283 raise ValueError("The truth value of an array with more than one "
284 "element is ambiguous. Use a.any() or a.all().")
285 __nonzero__ = __bool__
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().
Tam bir anlayış, sympy
kodu okumayı gerektirir , ancak üstünkörü bir bakış, onun girdinizi "tam matris" olarak işlemeye çalıştığını gösterir ve satırlara bakar. Hata, girişler üzerinde mantıksal işlemler yapmanın bir sonucu değildir, ancak bu sympy
seyrek matrisiniz üzerinde mantıksal bir test yapmanızdır. Satırın boş olup olmadığını kontrol etmeye çalışıyor (böylece atlayabilir).
SparseMatrix
belgeler en net olmayabilir, ancak çoğu örnek ya bir nokta diktesi ya da TÜM değerler artı şekilden oluşan düz bir dizi ya da düzensiz bir liste listesi gösterir. Matrisinize sıra sıra bakarak bu şekilde davranmaya çalıştığından şüpheleniyorum.
Ancak satırının M
kendisi seyrek bir matristir:
In [295]: [row for row in M]
Out[295]:
[<1x5 sparse matrix of type '<class 'numpy.float64'>'
with 0 stored elements in Compressed Sparse Row format>,
<1x5 sparse matrix of type '<class 'numpy.float64'>'
with 1 stored elements in Compressed Sparse Row format>,
...]
Ve bu satırın boş olup olmadığını kontrol etmeye çalışmak not row
şu hatayı üretir:
In [296]: not [row for row in M][0]
...
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().
Yani açıkça SparseMatrix
bir scipy.sparse
matrisi olduğu gibi işleyemez (en azından csr
veya csc
biçiminde ve muhtemelen diğerlerinde değil. Ayrıca scipy.sparse
, SparseMatrix
belgelerin hiçbir yerinde bahsedilmez !
yoğun diziden
Seyrek matrisi yoğun eşdeğerine dönüştürmek işe yarar:
In [297]: M.A
Out[297]:
array([[0. , 0. , 0. , 0. , 0. ],
[0. , 0.17737341, 0. , 0. , 0. ],
[0. , 0. , 0.12362175, 0.24324156, 0. ],
[0.7666429 , 0. , 0. , 0. , 0.21848551],
[0. , 0. , 0. , 0. , 0. ]])
In [298]: SparseMatrix(M.A)
Out[298]:
⎡ 0 0 0 0 0 ⎤
...⎦
Veya bir liste listesi:
SparseMatrix(M.A.tolist())
dikteden
dok
Biçimi olarak seyrek bir matris saklar dict
, sonra olabilen
In [305]: dict(M.todok())
Out[305]:
{(3, 0): 0.7666429046432961,
(1, 1): 0.17737340878962138,
(2, 2): 0.12362174819457106,
(2, 3): 0.24324155883057885,
(3, 4): 0.21848551209470246}
Girdi olarak iyi çalışan:
SparseMatrix(5,5,dict(M.todok()))
En verimli olanı bilmiyorum. Genel olarak sympy
biz (veya en azından ben) çalışırken verimlilik konusunda endişelenmeyin. Sadece çalıştırmanız yeterli. Verimlilik, numpy/scipy
dizilerin büyük olabileceği yerlerde daha önemlidir ve hızlı derlenen numpy yöntemlerinin kullanılması hızda büyük bir fark yaratır.
Son olarak - numpy
ve sympy
entegre edilmemiştir. Bu aynı zamanda seyrek versiyonlar için de geçerlidir. sympy
Python üzerine inşa edilmiştir, değil numpy
. Dolayısıyla liste ve dikteler şeklindeki girdiler en mantıklıdır.
from sympy.matrices import SparseMatrix
import scipy.sparse as sps
A = sps.random(100, 10, format="dok")
B = SparseMatrix(100, 10, dict(A.items()))
Verimli hafıza yapılarını seven birinin bakış açısından bu, uçuruma bakmak gibidir. Ama işe yarayacak.
Bu, hatanızın basitleştirilmiş bir sürümüdür.
from scipy import sparse
row = np.array([0, 0, 1, 2, 2, 2])
col = np.array([0, 2, 2, 0, 1, 2])
data = np.array([1, 2, 3, 4, 5, 6])
A = sparse.csc_matrix((data, (row, col)), shape=(3, 3))
Yani A
6 elemanlı seyrek matristir:
<3x3 sparse matrix of type '<class 'numpy.intc'>'
with 6 stored elements in Compressed Sparse Column format>
SparseMatrix()
Onu çağırmak , sahip olduğunuz aynı tür hatayı döndürür. Önce A
numpy dizisine dönüştürmek isteyebilirsiniz :
>>> SparseMatrix(A.todense())
Matrix([
[1, 0, 2],
[0, 0, 3],
[4, 5, 6]])