为什么我不能在第一个 "try:" 中将数据分配给部分稀疏矩阵?
Why can't I assign data to part of sparse matrix in the first "try:"?
我想为 crs 稀疏矩阵的一部分赋值(我知道这很昂贵,但在我的项目中并不重要)。
我试图将一个浮点变量分配给稀疏矩阵的一部分,但它第一次不起作用。但是,如果我在 "except" 中执行完全相同的操作,它将完美运行。
然后我尝试检查稀疏矩阵的 dtype 和它的一部分,由于某种原因它们是不同的。整个矩阵的数据类型是我分配的 float16,但矩阵的一部分具有 float32 dtype。
这是两个问题的一个小例子:
from scipy.sparse import csr_matrix
import numpy as np
frame = csr_matrix((10, 10),dtype=np.float16)
print "================\n================ Part 1\n================"
print "Let's assign a value to part of the sparse matrix:"
try:
frame[0:3,0:3] = np.float16(0.6)
print "The first attempt worked!"
except:
print "The first attempt didn't work"
print "let's try again :"
try:
frame[0:3,0:3] = np.float16(0.6)
print "The second attempt worked!"
except:
print "The second attempt didn't work"
print "================\n================ Part 2\n================"
print "Let's check the datatype:"
print "Frame dtype is:",; print frame.dtype
print "Part-of-frame dtype is",; print frame[0:3,0:3].dtype
结果如下:
================
================ Part 1
================
Let's assign a value to part of the sparse matrix:
The first attempt didn't work
let's try again :
The second attempt worked!
================
================ Part 2
================
Let's check the datatype:
Frame dtype is: float16
Part-of-frame dtype is float32
我仍然尝试将 np.float32 分配给稀疏矩阵的一部分,但我得到了相同的行为。有人可以解释发生了什么吗?
简答 - 问题出在 np.float16
;坚持使用通常的 32 或 64 个浮点数。
===============================
首先是一个工作案例(在 0.17 中)
In [334]: M=sparse.csr_matrix((5,5),dtype=np.float)
In [335]: M[:3,:3]=0.6
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
SparseEfficiencyWarning)
In [336]: M.A
Out[336]:
array([[ 0.6, 0.6, 0.6, 0. , 0. ],
[ 0.6, 0.6, 0.6, 0. , 0. ],
[ 0.6, 0.6, 0.6, 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. ]])
In [338]: M.data
Out[338]: array([ 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6])
如果我再次分配,我不会收到稀疏警告。
现在,如果我使用你的 dtype,我会收到稀疏警告,但也会收到 ValueError(你的通用 except
隐藏了它):
In [339]: M=sparse.csr_matrix((5,5),dtype=np.float16)
In [340]: M[:3,:3]=np.float16(0.6)
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
SparseEfficiencyWarning)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-340-aaecba748069> in <module>()
----> 1 M[:3,:3]=np.float16(0.6)
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in __setitem__(self, index, x)
654 return
655 i, j = self._swap((i.ravel(), j.ravel()))
--> 656 self._set_many(i, j, x.ravel())
657
658 def _setdiag(self, values, k):
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in _set_many(self, i, j, x)
738 j = j[mask]
739 j[j < 0] += N
--> 740 self._insert_many(i, j, x[mask])
741
742 def _insert_many(self, i, j, x):
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in _insert_many(self, i, j, x)
805 # TODO: only sort where necessary
806 self.has_sorted_indices = False
--> 807 self.sort_indices()
808
809 self.check_format(full_check=False)
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in sort_indices(self)
1039 if not self.has_sorted_indices:
1040 fn = _sparsetools.csr_sort_indices
-> 1041 fn(len(self.indptr) - 1, self.indptr, self.indices, self.data)
1042 self.has_sorted_indices = True
1043
ValueError: Output dtype not compatible with inputs.
如果我只是尝试将 csr
转换为密集型:
,我会得到同样的错误
In [346]: M=sparse.csr_matrix((5,5),dtype=np.float16)
In [347]: M.A
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-347-bdd665fbe1b0> in <module>()
----> 1 M.A
/usr/lib/python3/dist-packages/scipy/sparse/base.py in __getattr__(self, attr)
511 def __getattr__(self, attr):
512 if attr == 'A':
--> 513 return self.toarray()
514 elif attr == 'T':
515 return self.transpose()
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in toarray(self, order, out)
938 def toarray(self, order=None, out=None):
939 """See the docstring for `spmatrix.toarray`."""
--> 940 return self.tocoo(copy=False).toarray(order=order, out=out)
941
942 ...
ValueError: Output dtype not compatible with inputs.
所以问题不在于分配,而在于处理 dtype
。它看起来像一个错误,但您可以通过不使用此 dtype 来避免它。
和lil
矩阵也有这个dtype的问题:
In [348]: M=sparse.lil_matrix((5,5),dtype=np.float16)
In [349]: M[:3,:3]=np.float16(0.6)
...
KeyError: (dtype('int32'), dtype('float16'))
在转换的某些时候,指定的 dtype 没有被保留。
但为什么首先要使用 float16
? float32 和 float64 是普通的 numpy 浮点数。
即使我成功创建了一个 np.float16
矩阵,在大多数稀疏操作中也不会保留该 dtype:
In [374]: M=sparse.csr_matrix(np.arange(9).reshape(3,3), dtype=np.float16)
In [375]: M.data
Out[375]: array([ 1., 2., 3., 4., 5., 6., 7., 8.], dtype=float16)
In [376]:
In [376]: M
Out[376]:
<3x3 sparse matrix of type '<class 'numpy.float16'>'
with 8 stored elements in Compressed Sparse Row format>
In [377]: M.A # same error converting to dense
...
ValueError: Output dtype not compatible with inputs.
In [378]: M.T # dtype kept during transpose
Out[378]:
<3x3 sparse matrix of type '<class 'numpy.float16'>'
with 8 stored elements in Compressed Sparse Column format>
dtype 不通过乘法或索引保留。编译后的矩阵乘法代码很可能是为 32 和 64(常规 C 浮点数和双精度数)编写的,而不是 16。
In [379]: M*M
Out[379]:
<3x3 sparse matrix of type '<class 'numpy.float32'>'
with 9 stored elements in Compressed Sparse Row format>
In [380]: M[0,:]
Out[380]:
<1x3 sparse matrix of type '<class 'numpy.float32'>'
with 2 stored elements in Compressed Sparse Row format>
我不知道文档是否警告 float16
,但我认为它几乎没用。
我想为 crs 稀疏矩阵的一部分赋值(我知道这很昂贵,但在我的项目中并不重要)。 我试图将一个浮点变量分配给稀疏矩阵的一部分,但它第一次不起作用。但是,如果我在 "except" 中执行完全相同的操作,它将完美运行。
然后我尝试检查稀疏矩阵的 dtype 和它的一部分,由于某种原因它们是不同的。整个矩阵的数据类型是我分配的 float16,但矩阵的一部分具有 float32 dtype。
这是两个问题的一个小例子:
from scipy.sparse import csr_matrix
import numpy as np
frame = csr_matrix((10, 10),dtype=np.float16)
print "================\n================ Part 1\n================"
print "Let's assign a value to part of the sparse matrix:"
try:
frame[0:3,0:3] = np.float16(0.6)
print "The first attempt worked!"
except:
print "The first attempt didn't work"
print "let's try again :"
try:
frame[0:3,0:3] = np.float16(0.6)
print "The second attempt worked!"
except:
print "The second attempt didn't work"
print "================\n================ Part 2\n================"
print "Let's check the datatype:"
print "Frame dtype is:",; print frame.dtype
print "Part-of-frame dtype is",; print frame[0:3,0:3].dtype
结果如下:
================
================ Part 1
================
Let's assign a value to part of the sparse matrix:
The first attempt didn't work
let's try again :
The second attempt worked!
================
================ Part 2
================
Let's check the datatype:
Frame dtype is: float16
Part-of-frame dtype is float32
我仍然尝试将 np.float32 分配给稀疏矩阵的一部分,但我得到了相同的行为。有人可以解释发生了什么吗?
简答 - 问题出在 np.float16
;坚持使用通常的 32 或 64 个浮点数。
===============================
首先是一个工作案例(在 0.17 中)
In [334]: M=sparse.csr_matrix((5,5),dtype=np.float)
In [335]: M[:3,:3]=0.6
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
SparseEfficiencyWarning)
In [336]: M.A
Out[336]:
array([[ 0.6, 0.6, 0.6, 0. , 0. ],
[ 0.6, 0.6, 0.6, 0. , 0. ],
[ 0.6, 0.6, 0.6, 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. , 0. ]])
In [338]: M.data
Out[338]: array([ 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6])
如果我再次分配,我不会收到稀疏警告。
现在,如果我使用你的 dtype,我会收到稀疏警告,但也会收到 ValueError(你的通用 except
隐藏了它):
In [339]: M=sparse.csr_matrix((5,5),dtype=np.float16)
In [340]: M[:3,:3]=np.float16(0.6)
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
SparseEfficiencyWarning)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-340-aaecba748069> in <module>()
----> 1 M[:3,:3]=np.float16(0.6)
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in __setitem__(self, index, x)
654 return
655 i, j = self._swap((i.ravel(), j.ravel()))
--> 656 self._set_many(i, j, x.ravel())
657
658 def _setdiag(self, values, k):
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in _set_many(self, i, j, x)
738 j = j[mask]
739 j[j < 0] += N
--> 740 self._insert_many(i, j, x[mask])
741
742 def _insert_many(self, i, j, x):
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in _insert_many(self, i, j, x)
805 # TODO: only sort where necessary
806 self.has_sorted_indices = False
--> 807 self.sort_indices()
808
809 self.check_format(full_check=False)
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in sort_indices(self)
1039 if not self.has_sorted_indices:
1040 fn = _sparsetools.csr_sort_indices
-> 1041 fn(len(self.indptr) - 1, self.indptr, self.indices, self.data)
1042 self.has_sorted_indices = True
1043
ValueError: Output dtype not compatible with inputs.
如果我只是尝试将 csr
转换为密集型:
In [346]: M=sparse.csr_matrix((5,5),dtype=np.float16)
In [347]: M.A
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-347-bdd665fbe1b0> in <module>()
----> 1 M.A
/usr/lib/python3/dist-packages/scipy/sparse/base.py in __getattr__(self, attr)
511 def __getattr__(self, attr):
512 if attr == 'A':
--> 513 return self.toarray()
514 elif attr == 'T':
515 return self.transpose()
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py in toarray(self, order, out)
938 def toarray(self, order=None, out=None):
939 """See the docstring for `spmatrix.toarray`."""
--> 940 return self.tocoo(copy=False).toarray(order=order, out=out)
941
942 ...
ValueError: Output dtype not compatible with inputs.
所以问题不在于分配,而在于处理 dtype
。它看起来像一个错误,但您可以通过不使用此 dtype 来避免它。
和lil
矩阵也有这个dtype的问题:
In [348]: M=sparse.lil_matrix((5,5),dtype=np.float16)
In [349]: M[:3,:3]=np.float16(0.6)
...
KeyError: (dtype('int32'), dtype('float16'))
在转换的某些时候,指定的 dtype 没有被保留。
但为什么首先要使用 float16
? float32 和 float64 是普通的 numpy 浮点数。
即使我成功创建了一个 np.float16
矩阵,在大多数稀疏操作中也不会保留该 dtype:
In [374]: M=sparse.csr_matrix(np.arange(9).reshape(3,3), dtype=np.float16)
In [375]: M.data
Out[375]: array([ 1., 2., 3., 4., 5., 6., 7., 8.], dtype=float16)
In [376]:
In [376]: M
Out[376]:
<3x3 sparse matrix of type '<class 'numpy.float16'>'
with 8 stored elements in Compressed Sparse Row format>
In [377]: M.A # same error converting to dense
...
ValueError: Output dtype not compatible with inputs.
In [378]: M.T # dtype kept during transpose
Out[378]:
<3x3 sparse matrix of type '<class 'numpy.float16'>'
with 8 stored elements in Compressed Sparse Column format>
dtype 不通过乘法或索引保留。编译后的矩阵乘法代码很可能是为 32 和 64(常规 C 浮点数和双精度数)编写的,而不是 16。
In [379]: M*M
Out[379]:
<3x3 sparse matrix of type '<class 'numpy.float32'>'
with 9 stored elements in Compressed Sparse Row format>
In [380]: M[0,:]
Out[380]:
<1x3 sparse matrix of type '<class 'numpy.float32'>'
with 2 stored elements in Compressed Sparse Row format>
我不知道文档是否警告 float16
,但我认为它几乎没用。