SparkMLlib中的稀疏矩阵写法是这样的:
Matrices.sparse(3,2,Array(0,1,3), Array(0,2,1), Array(9,6,8))
或者写成这样:
Matrices.sparse(3, 2, [0, 1, 3], [0, 2, 1], [9, 6, 8])
这是一个3×2的即3行2列的矩阵写法
这个东西执行完结果是这样的:
(0,0) 9.0
(2,1) 6.0
(1,1) 8.0
也就是这样的稠密矩阵:
[9, 0]
[0, 8]
[0, 6]
通过对比写法,我们很容易理解其中的参数 ,第一个3就是行数,第二个2是列数,第二个Array是非0元素所在行数,第三个Array是非0元素数值
很难理解的是第一个数组:Array(0,1,3)
Array(0,1,3)中的第一个元素是0,表示迭代开始,最后一个元素3则表示非0元素的总数 。关键是中间的这个值2。
把把Array(0,1,3)改成Array(0,2,3)后:
Matrix = Matrices.sparse(3,2,Array(0,2,3), Array(0,2,1), Array(9,6,8))
执行输出结果为:
(0,0) 9.0
(2,0) 6.0
(1,1) 8.0
也就是这样的稠密矩阵:
[9, 0]
[0, 8]
[6, 0]
可以看到6的位置变化了,从第二列变到了第一列((2,1)-->(2,0))
那么可以肯定的是,这个位置代表的是第一列的点的数量
综合之前的分析,我们可以得到一个结论,这个Array是从0开始,1号位代表第一列元素个数,第二列代表第一列元素个数+第二列元素个数.
可以看到,这是一个累加过程,第一列有2个,第二列有1个,第三列有3个 。
第一个数组Array(0,2,3)中,第一个0表示迭代开始,第二个元素2表示第一列有2个非0元素,第三个元素3表示第一列非0元素数与第二列非0元素数的累加和(前面列的非0元素总个数)。
如果有较多列,比如有3列,并且第三列的非0元素有一个,则第一个数组则为Array(0,2,3,4)。这里的4就是每一列非0元素个数累加(2 + 1 + 1 = 4)的结果。例如:
Matrices.sparse(3,3,[0, 3, 3, 4], [0, 2, 1, 1], [9, 6, 8,10]),这是一个3×3也就是3行3列的写法,第一个数组[0, 3, 3, 4]中,第一个元素0表示开始迭代,第二个元素3表示第一列非0元素的个数为3个,第三个元素3表示第一列和第二列的非0元素个数累加和,这表明第二列的非0元素个数为0个(因为3+0=3),第4个元素4表示第一、二、三列的非0元素个数的累加和,这说明第三列有一个非0元素(因为3+0+1=4)。Matrices.sparse(3,3,[0, 3, 3, 4], [0, 2, 1, 1], [9, 6, 8,10])
(0,0) 9.0
(2,0) 6.0
(1,0) 8.0
(1,1) 10.0
虽然一个数组[0, 3, 3, 4]和[0, 3, 4, 4]。
这和Matrices.sparse(3,3,[0, 3, 4, 4], [0, 2, 1, 1], [9, 6, 8,10])输出的结果相同,
执行结果如下:
(0,0) 9.0
(2,0) 6.0
(1,0) 8.0
(1,1) 10.0
也就是这样的稠密矩阵:
[9, 0, 0]
[8, 10,0]
[6, 0, 0]
结果相同的原因是,“先标记对角线”,之后根据每列点数不同进行调整。
Matrices.sparse(3,3,[0, 3, 4, 5], [0, 2, 1, 2, 2], [9, 6, 8,10,11])
(0,0) 9.0
(2,0) 6.0
(1,0) 8.0
(2,1) 10.0
(2,2) 11.0
也就是这样的稠密矩阵:
[9, 0, 0]
[8, 10,11]
[6, 0, 0]
结论:
Matrix = Matrices.sparse(3,2,Array(0,2,3), Array(0,2,1), Array(9,6,8))
(1)3,2表示行列数。
(2)Array(0,2,3),0表示开始迭代,1表示第一列非0元素个数,3表示第二列与第一列的非0元素个数累加和。
(3)Array(0,2,1)表示非0元素分别对应的行号。
(4)Array(9,6,8))表示非0元素。
这个写法就很好理解了,先圈出行数和列数,都标记为0,再将各元素按照所属行进行有序排列,先标记对角线,之后根据每列点数不同进行调整。