如何在for循环中使用vstack以便将csr_matrix矩阵附加到一起

时间:2015-10-07 13:56:48

标签: python numpy scipy

我正在使用以下代码片段将csr_matrix类型的矩阵连接在一起。它基于How to flatten a csr_matrix and append it to another csr_matrix?

#! /usr/bin/python
# -*- coding: utf-8 -*-
import re, sys
import os
import numpy

from scipy.sparse import csr_matrix
from scipy.sparse import vstack


if __name__ == "__main__": 

  centroids = []
  for i in range(0,3):
    a = csr_matrix([[i,i,i]])
    centroids = vstack((centroids, a), format='csr')

  print "centroids : " + str(centroids.shape[0]) +"  "+ str(centroids.shape[1])

作为输出我正在

centroids : 4  3

质心的大小应为3而不是4.我是否正确连接它们?

我尝试了以下内容,看看是否可以忽略第一行:

from sklearn.metrics.pairwise import euclidean_distances
matrix = euclidean_distances(centroids[1:][:], centroids[1:][:])
print matrix
[[ 0.          1.73205081  3.46410162]
 [ 1.73205081  0.          1.73205081]
 [ 3.46410162  1.73205081  0.        ]]

听起来不错。

3 个答案:

答案 0 :(得分:3)

不要在循环中使用vstack,因为在每次迭代中更改矩阵的大小和稀疏性都很昂贵。 而是做:

centroids = []
for i in range(3):
  a = csr_matrix([[i, i, i]])
  centroids.append(a)
centroids = vstack(centroids, format="csr")

答案 1 :(得分:2)

[]csr_matrix([[i,i,i]])的串联可以解决您的问题。

centroids = []
a = csr_matrix([[1,2,3]])
centroids = vstack((centroids, a), format='csr')
print centroids.toarray()

给你

array([[ 0.,  0.,  0.],
       [ 1.,  2.,  3.]])

所以只需从1

开始递增计数器
centroids = []
for i in range(1,3):
    a = csr_matrix([[i,i,i]])
    centroids = vstack((centroids, a), format='csr')

顺便说一下,堆叠csr_matrices效率非常低,因为centroids的稀疏性在每次迭代中都会不断变化。也许,如果存储行,列和系数,然后立即调用它们sparse,则会更好。看看here

答案 2 :(得分:1)

DeviceIoControl()将初始vstack值视为1行矩阵

centroids

In [1]: from scipy import sparse In [2]: centroids = [] In [3]: a = sparse.csr_matrix([[0,0,0]]) In [4]: b=sparse.vstack((centroids,a),format='csr') In [5]: b Out[5]: <2x3 sparse matrix of type '<class 'numpy.float64'>' with 0 stored elements in Compressed Sparse Row format> In [6]: b.A Out[6]: array([[ 0., 0., 0.], [ 0., 0., 0.]]) 全为零,因此它是a,其中包含0个存储元素。为了使事情更明显,请使用非零值使csr

a

你应该在迭代后打印In [7]: a = sparse.csr_matrix([[1,1,1]]) In [8]: b=sparse.vstack((centroids,a),format='csr') In [9]: b Out[9]: <2x3 sparse matrix of type '<class 'numpy.float64'>' with 3 stored elements in Compressed Sparse Row format> In [10]: b.A Out[10]: array([[ 0., 0., 0.], [ 1., 1., 1.]]) ;问题的本质会更加明显。

你在做什么就像:

centroids

是的,您可以通过切掉第一行来使用In [12]: x=[0] In [13]: for i in range(3): x.append(i) In [14]: x Out[14]: [0, 0, 1, 2] ,但这是解决更基本问题的笨拙方法 - 迭代的起始值。

如果我从带有0行的centroids开始,我可以避免问题

centroids

如果您必须使用In [30]: centroids = sparse.csr_matrix((0,3),dtype=int) In [31]: b=sparse.vstack((centroids,a),format='csr') In [32]: b Out[32]: <1x3 sparse matrix of type '<class 'numpy.int32'>' with 3 stored elements in Compressed Sparse Row format> In [33]: b.A Out[33]: array([[1, 1, 1]]) 之类的内容进行迭代,请确保以有意义的值开头。

但正如其他人指出的那样,重复sparse.vstack构建稀疏数组是一个低效的过程。