如何有效地将scipy稀疏和numpy数组拆分成更小的N个不相等的块?

时间:2017-03-27 14:24:06

标签: python python-3.x numpy machine-learning scipy

检查documentationthis question后,我尝试按如下方式拆分numpy数组和稀疏scipy矩阵:

>>>print(X.shape) 
(2399, 39999)

>>>print(type(X))
<class 'scipy.sparse.csr.csr_matrix'>

>>>print(X.toarray())

[[0 0 0 ..., 0 0 0]
 [0 0 0 ..., 0 0 0]
 [0 0 0 ..., 0 0 0]
 ..., 
 [0 0 0 ..., 0 0 0]
 [0 0 0 ..., 0 0 0]
 [0 0 0 ..., 0 0 0]]

然后:

new_array = np.split(X,3)

输出:

ValueError: array split does not result in an equal division

然后我试着:

new_array = np.hsplit(X,3)

输出:

ValueError: bad axis1 argument to swapaxes

因此,如何将数组拆分为N个不同大小的块?

2 个答案:

答案 0 :(得分:3)

制作稀疏矩阵:

In [62]: M=(sparse.rand(10,3,.3,'csr')*10).astype(int)
In [63]: M
Out[63]: 
<10x3 sparse matrix of type '<class 'numpy.int32'>'
    with 9 stored elements in Compressed Sparse Row format>
In [64]: M.A
Out[64]: 
array([[0, 7, 0],
       [0, 0, 0],
       [0, 0, 0],
       [0, 0, 0],
       [0, 0, 5],
       [0, 0, 2],
       [0, 0, 6],
       [0, 4, 4],
       [7, 1, 0],
       [0, 0, 2]])

密集的等价物容易分裂。 array_split处理不相等的块,但您也可以拼出分割,如另一个答案中所示。

In [65]: np.array_split(M.A, 3)
Out[65]: 
[array([[0, 7, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]]), array([[0, 0, 5],
        [0, 0, 2],
        [0, 0, 6]]), array([[0, 4, 4],
        [7, 1, 0],
        [0, 0, 2]])]

一般来说,numpy函数不能直接在稀疏矩阵上运行。它们不是子类。除非函数将操作委托给数组自己的方法,否则该函数可能无效。该函数通常以np.asarray(M)开头,与M.toarray()不同(自己试一试)。

但是split只不过是沿着所需的轴切片。我可以用:

生成相同的4,2,3分割
In [143]: alist = [M[0:4,:], M[4:7,:], M[7:10]]
In [144]: alist
Out[144]: 
[<4x3 sparse matrix of type '<class 'numpy.int32'>'
    with 1 stored elements in Compressed Sparse Row format>,
 <3x3 sparse matrix of type '<class 'numpy.int32'>'
    with 3 stored elements in Compressed Sparse Row format>,
 <3x3 sparse matrix of type '<class 'numpy.int32'>'
    with 5 stored elements in Compressed Sparse Row format>]
In [145]: [m.A for m in alist]
Out[145]: 
[array([[0, 7, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]], dtype=int32), array([[0, 0, 5],
        [0, 0, 2],
        [0, 0, 6]], dtype=int32), array([[0, 4, 4],
        [7, 1, 0],
        [0, 0, 2]], dtype=int32)]

其余的是行政细节。

我应该补充一点,稀疏切片永远不是视图。它们是新的稀疏矩阵,具有自己的data属性。

使用列表中的拆分索引,我们可以使用简单的迭代构造拆分列表:

In [146]: idx = [0,4,7,10]
In [149]: alist = []
In [150]: for i in range(len(idx)-1):
     ...:     alist.append(M[idx[i]:idx[i+1]])   

我还没有弄清楚如何构建idx的详细信息,虽然10中的M.shape[0]是明显的起点。

对于偶数分裂(适合)

In [160]: [M[i:i+5,:] for i in range(0,M.shape[0],5)]
Out[160]: 
[<5x3 sparse matrix of type '<class 'numpy.int32'>'
    with 2 stored elements in Compressed Sparse Row format>,
 <5x3 sparse matrix of type '<class 'numpy.int32'>'
    with 7 stored elements in Compressed Sparse Row format>]

答案 1 :(得分:1)

首先,将scipy.sparse.csr_matrix转换为numpy ndarray,然后将列表传递给numpy.split(ary, indices_or_sections, axis=0)

  

如果indices_or_sections是排序整数的1-D数组,则条目指示沿轴分割数组的位置。例如,对于轴= 0,[2,3]将导致   进制[:2]   进制[2:3]   进制[3:

https://docs.scipy.org/doc/numpy/reference/generated/numpy.split.html

X1, X2, X3 = np.split(X.toarray(), [1000,2000])