scipy.sparse.hstack(([1], [2])) -> "ValueError: blocks must be 2-D". Why?
scipy.sparse.hstack(([1], [2])) -> "ValueError: blocks must be 2-D". Why?
scipy.sparse.hstack((1, [2]))
和 scipy.sparse.hstack((1, [2]))
效果很好,但 scipy.sparse.hstack(([1], [2]))
不行。为什么会这样?
这是我系统上发生的事情的痕迹:
C:\Anaconda>python
Python 2.7.10 |Anaconda 2.3.0 (64-bit)| (default, May 28 2015, 16:44:52) [MSC v.
1500 64 bit (AMD64)] on win32
>>> import scipy.sparse
>>> scipy.sparse.hstack((1, [2]))
<1x2 sparse matrix of type '<type 'numpy.int32'>'
with 2 stored elements in COOrdinate format>
>>> scipy.sparse.hstack((1, 2))
<1x2 sparse matrix of type '<type 'numpy.int32'>'
with 2 stored elements in COOrdinate format>
>>> scipy.sparse.hstack(([1], [2]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Anaconda\lib\site-packages\scipy\sparse\construct.py", line 456, in h
stack
return bmat([blocks], format=format, dtype=dtype)
File "C:\Anaconda\lib\site-packages\scipy\sparse\construct.py", line 539, in b
mat
raise ValueError('blocks must be 2-D')
ValueError: blocks must be 2-D
>>> scipy.version.full_version
'0.16.0'
>>>
在 scipy.sparse.hstack((1, [2]))
的第一种情况下,数字 1 被解释为标量值,数字 2 被解释为密集矩阵,因此当您将这两者组合在一起时,数据类型为强制使它们都是标量,您可以正常将其与 scipy.sparse.hstack
结合使用。
这里有一些更多的测试来证明对于多个值也是如此:
In [31]: scipy.sparse.hstack((1,2,[3],[4]))
Out[31]:
<1x4 sparse matrix of type '<type 'numpy.int64'>'
with 4 stored elements in COOrdinate format>
In [32]: scipy.sparse.hstack((1,2,[3],[4],5,6))
Out[32]:
<1x6 sparse matrix of type '<type 'numpy.int64'>'
with 6 stored elements in COOrdinate format>
In [33]: scipy.sparse.hstack((1,[2],[3],[4],5,[6],7))
Out[33]:
<1x7 sparse matrix of type '<type 'numpy.int64'>'
如您所见,如果 hstack
中至少有一个标量,这似乎有效。
但是,当您尝试执行 scipy.sparse.hstack(([1],[2]))
的第二种情况时,它们不再都是标量,它们都是稠密矩阵,您不能将 scipy.sparse.hstack
与纯稠密一起使用矩阵。
重现:
In [34]: scipy.sparse.hstack(([1],[2]))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-45-cd79952b2e14> in <module>()
----> 1 scipy.sparse.hstack(([1],[2]))
/usr/local/lib/python2.7/site-packages/scipy/sparse/construct.pyc in hstack(blocks, format, dtype)
451
452 """
--> 453 return bmat([blocks], format=format, dtype=dtype)
454
455
/usr/local/lib/python2.7/site-packages/scipy/sparse/construct.pyc in bmat(blocks, format, dtype)
531
532 if blocks.ndim != 2:
--> 533 raise ValueError('blocks must be 2-D')
534
535 M,N = blocks.shape
ValueError: blocks must be 2-D
查看此 post 以获得更多见解:Scipy error with sparse hstack
因此,如果你想成功地使用这两个矩阵,你必须先将它们稀疏化,然后再合并它们:
In [36]: A = scipy.sparse.coo_matrix([1])
In [37]: B = scipy.sparse.coo_matrix([2])
In [38]: C = scipy.sparse.hstack([A, B])
In [39]: C
Out[39]:
<1x2 sparse matrix of type '<type 'numpy.int64'>'
with 2 stored elements in COOrdinate format>
有趣的是,如果您尝试使用 hstack
或 numpy.hstack
的密集版本,那么它是完全可以接受的:
In [48]: import numpy as np
In [49]: np.hstack((1, [2]))
Out[49]: array([1, 2])
.. 稀疏矩阵表示 ¯\_(ツ)_/¯
.
编码详情为:
def hstack(blocks ...):
return bmat([blocks], ...)
def bmat(blocks, ...):
blocks = np.asarray(blocks, dtype='object')
if blocks.ndim != 2:
raise ValueError('blocks must be 2-D')
(continue)
所以尝试你的替代方案(记住额外的 []
):
In [392]: np.asarray([(1,2)],dtype=object)
Out[392]: array([[1, 2]], dtype=object)
In [393]: np.asarray([(1,[2])],dtype=object)
Out[393]: array([[1, [2]]], dtype=object)
In [394]: np.asarray([([1],[2])],dtype=object)
Out[394]:
array([[[1],
[2]]], dtype=object)
In [395]: _.shape
Out[395]: (1, 2, 1)
最后一个案例(您的问题案例)失败了,因为结果是 3d。
有 2 个稀疏矩阵(预期输入):
In [402]: np.asarray([[a,a]], dtype=object)
Out[402]:
array([[ <1x1 sparse matrix of type '<class 'numpy.int32'>'
with 1 stored elements in COOrdinate format>,
<1x1 sparse matrix of type '<class 'numpy.int32'>'
with 1 stored elements in COOrdinate format>]], dtype=object)
In [403]: _.shape
Out[403]: (1, 2)
hstack
正在利用 bmat
格式,将矩阵列表转换为嵌套的 (2d) 矩阵列表。 bmat
是一种将二维稀疏矩阵数组组合成一个更大矩阵的方法。跳过首先制作这些稀疏矩阵的步骤可能有效,也可能无效。代码和文档不做任何承诺。
scipy.sparse.hstack((1, [2]))
和 scipy.sparse.hstack((1, [2]))
效果很好,但 scipy.sparse.hstack(([1], [2]))
不行。为什么会这样?
这是我系统上发生的事情的痕迹:
C:\Anaconda>python
Python 2.7.10 |Anaconda 2.3.0 (64-bit)| (default, May 28 2015, 16:44:52) [MSC v.
1500 64 bit (AMD64)] on win32
>>> import scipy.sparse
>>> scipy.sparse.hstack((1, [2]))
<1x2 sparse matrix of type '<type 'numpy.int32'>'
with 2 stored elements in COOrdinate format>
>>> scipy.sparse.hstack((1, 2))
<1x2 sparse matrix of type '<type 'numpy.int32'>'
with 2 stored elements in COOrdinate format>
>>> scipy.sparse.hstack(([1], [2]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Anaconda\lib\site-packages\scipy\sparse\construct.py", line 456, in h
stack
return bmat([blocks], format=format, dtype=dtype)
File "C:\Anaconda\lib\site-packages\scipy\sparse\construct.py", line 539, in b
mat
raise ValueError('blocks must be 2-D')
ValueError: blocks must be 2-D
>>> scipy.version.full_version
'0.16.0'
>>>
在 scipy.sparse.hstack((1, [2]))
的第一种情况下,数字 1 被解释为标量值,数字 2 被解释为密集矩阵,因此当您将这两者组合在一起时,数据类型为强制使它们都是标量,您可以正常将其与 scipy.sparse.hstack
结合使用。
这里有一些更多的测试来证明对于多个值也是如此:
In [31]: scipy.sparse.hstack((1,2,[3],[4]))
Out[31]:
<1x4 sparse matrix of type '<type 'numpy.int64'>'
with 4 stored elements in COOrdinate format>
In [32]: scipy.sparse.hstack((1,2,[3],[4],5,6))
Out[32]:
<1x6 sparse matrix of type '<type 'numpy.int64'>'
with 6 stored elements in COOrdinate format>
In [33]: scipy.sparse.hstack((1,[2],[3],[4],5,[6],7))
Out[33]:
<1x7 sparse matrix of type '<type 'numpy.int64'>'
如您所见,如果 hstack
中至少有一个标量,这似乎有效。
但是,当您尝试执行 scipy.sparse.hstack(([1],[2]))
的第二种情况时,它们不再都是标量,它们都是稠密矩阵,您不能将 scipy.sparse.hstack
与纯稠密一起使用矩阵。
重现:
In [34]: scipy.sparse.hstack(([1],[2]))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-45-cd79952b2e14> in <module>()
----> 1 scipy.sparse.hstack(([1],[2]))
/usr/local/lib/python2.7/site-packages/scipy/sparse/construct.pyc in hstack(blocks, format, dtype)
451
452 """
--> 453 return bmat([blocks], format=format, dtype=dtype)
454
455
/usr/local/lib/python2.7/site-packages/scipy/sparse/construct.pyc in bmat(blocks, format, dtype)
531
532 if blocks.ndim != 2:
--> 533 raise ValueError('blocks must be 2-D')
534
535 M,N = blocks.shape
ValueError: blocks must be 2-D
查看此 post 以获得更多见解:Scipy error with sparse hstack
因此,如果你想成功地使用这两个矩阵,你必须先将它们稀疏化,然后再合并它们:
In [36]: A = scipy.sparse.coo_matrix([1])
In [37]: B = scipy.sparse.coo_matrix([2])
In [38]: C = scipy.sparse.hstack([A, B])
In [39]: C
Out[39]:
<1x2 sparse matrix of type '<type 'numpy.int64'>'
with 2 stored elements in COOrdinate format>
有趣的是,如果您尝试使用 hstack
或 numpy.hstack
的密集版本,那么它是完全可以接受的:
In [48]: import numpy as np
In [49]: np.hstack((1, [2]))
Out[49]: array([1, 2])
.. 稀疏矩阵表示 ¯\_(ツ)_/¯
.
编码详情为:
def hstack(blocks ...):
return bmat([blocks], ...)
def bmat(blocks, ...):
blocks = np.asarray(blocks, dtype='object')
if blocks.ndim != 2:
raise ValueError('blocks must be 2-D')
(continue)
所以尝试你的替代方案(记住额外的 []
):
In [392]: np.asarray([(1,2)],dtype=object)
Out[392]: array([[1, 2]], dtype=object)
In [393]: np.asarray([(1,[2])],dtype=object)
Out[393]: array([[1, [2]]], dtype=object)
In [394]: np.asarray([([1],[2])],dtype=object)
Out[394]:
array([[[1],
[2]]], dtype=object)
In [395]: _.shape
Out[395]: (1, 2, 1)
最后一个案例(您的问题案例)失败了,因为结果是 3d。
有 2 个稀疏矩阵(预期输入):
In [402]: np.asarray([[a,a]], dtype=object)
Out[402]:
array([[ <1x1 sparse matrix of type '<class 'numpy.int32'>'
with 1 stored elements in COOrdinate format>,
<1x1 sparse matrix of type '<class 'numpy.int32'>'
with 1 stored elements in COOrdinate format>]], dtype=object)
In [403]: _.shape
Out[403]: (1, 2)
hstack
正在利用 bmat
格式,将矩阵列表转换为嵌套的 (2d) 矩阵列表。 bmat
是一种将二维稀疏矩阵数组组合成一个更大矩阵的方法。跳过首先制作这些稀疏矩阵的步骤可能有效,也可能无效。代码和文档不做任何承诺。