spark矩陣向量 矩陣矩陣相乘

2021-06-22 18:57:16 字數 3250 閱讀 4258

import org.apache.spark.util._

val paramatrix1 = sc.parallelize(list(vector(2, 2, 4), vector(3, 2, 1), vector(1, 3, 2)))//首先,在spark shell中將乙個矩陣按照行進行並行化,

val vec1 =vector(1,2,4)//定義乙個向量

val m1=paramatrix1.map(_ dot(vec1))//dot 操作將兩個向量相乘,得到點積。這裡需要注意的是,雖然並行操作並不保證先後順序,但是結果是依然有先後順序的。

//mapreduce 在做矩陣向量相乘的時候,是按照把每個元素的行作為key。每個元素的值作為value,reduce的過程是相同的key的value相加,得到結果。

spark也可以這樣做,但是並沒有優勢,每個元素都需要並行化成乙個rdd,那麼m*m的矩陣就需要有m^2個task。而按行相乘,只需要m個task,在實際的應用中足夠了。

如果檔案超大,不能在記憶體中放入,那麼需要對矩陣和向量進行切割。切割方式如下:

切割之後,把相應的部分乘起來即可。

2,矩陣矩陣相乘。

s=m*n。把矩陣n的每個列作為上面的乙個向量。即變成了矩陣和向量相乘,然後按照上述步驟計算即可。得到的結果是乙個s的乙個列。但是rdd提供了乙個函式cartesian可以為這種計算提供便利。cartesian可以返回兩個rdd的所有組合。並且保證秩序。因此可以很方便來進行矩陣運算。

val paramatrix1 = sc.parallelize(list(vector(2, 2, 4), vector(3, 2, 1), vector(1, 3, 2)))//矩陣m

val paramatrix2 = sc.parallelize(list(vector(2, 3, 1), vector(2, 2, 3), vector(4, 1, 2)))//矩陣n ,the same matrix as m .只是儲存的方式不一樣,n是按列儲存

val m2= paramatrix1.cartesian(paramatrix2)#排序次序是rdd1的第乙個元素依次和rdd2的所有元素,然後是rdd1的第二個元素依次和rdd2 的所有元素。 //

因此取前n個元素,構成了結果矩陣s(n*n)的第一行,(n+1)到2n個元素,構成了s的第二行

val temp=m2.map(x=>x._1.dot(x._2))//然後把每個pair裡面的元素取點積.再按照上面的排序取出矩陣,就是最終的結果。

但是上述過程存在乙個問題。就是中間結果的資料量將是原始矩陣的n倍。因此在大數量的時候也可以考慮矩陣向量的乘法來比較一下兩者的效能。

當然,針對稀疏矩陣還可以通過對矩陣的元素按行列來索引資料。通過構建小的pair來計算矩陣相乘。

下面介紹實現思想和方法。

假設m由(i,j,v)構成,n由(j,k,w構成),其中i,j為矩陣元素的行和列索引。那麼s=m*n的元素(i,k,p)的計算如下式。

從上式可以看出,(i,k,p)的計算是由m的i行和n的k列構成。由於m(ij)和n(j,k)中的j是共有元素,可以按j來構造鍵值。

即每個m中的元素構建為(j,(i,v))。每個n中的元素構建為(j,(k,w))。然後兩個元素相乘。構造成((i,k),j,v*w)。最後按鍵值(i,k)相加,構成((i,k),p)。

**如下:

首先構造兩個矩陣,按元素並行化,不出現的元素即為0

val paramatrix1 = sc.parallelize(list(vector(1, 1, 1), vector(2, 2, 2),vector(2, 1, 3), vector(3, 3, 4)))//有四個元素

val paramatrix2 = sc.parallelize(list(vector(1, 1, 5), vector(2, 2, 6),

vector(2, 3, 7),

vector(3, 3, 8)))

val tempm = paramatrix1.map(x=>(x(1),(x(0),x(2))))//轉化成(j,(i,v))

val tempn = paramatrix2.map(x=>(x(0),(x(1),x(2))))//轉化成

(j,(k,w))

val temp1= tempm.cartesian(tempn).filter(x=>x._1._1==x._2._1)//將具有相同j的所有i.k都聚到同乙個pair中。

val temp2=temp1.map(x=>((x._1._2._1,x._2._2._1),x._1._2._2*x._2._2._2))// 重塑這個pair,使之具有((i,k),v*w)形式。

val te***=temp2.

reducebykey(_+_)//具有相同pair的元素相加。即得到最終結果。

經測試結果正確。下面再測試乙個完全沒有零元素的3*3矩陣

val paramatrix1 = sc.parallelize(list(vector(1, 1, 1), vector(1, 2, 3),vector(1, 3, 6), vector(2, 1, 3), vector(2, 2, 2)

, vector(2, 3, 5)

, vector(3, 1, 1)

, vector(3, 2, 2)

, vector(3, 3, 4)))//c(1,3,1,3,2,2,6,5,4)

val paramatrix2 =sc.parallelize(list(vector(1, 1, 5), vector(1, 2, 3),vector(1, 3, 3), vector(2, 1, 1)

, vector(2, 2, 6)

, vector(2, 3, 7)

, vector(3, 1, 4)

, vector(3, 2, 1)

, vector(3, 3, 8)

))//

結果為array(((3.0,1.0),23.0), ((2.0,3.0),63.0), ((1.0,2.0),27.0), ((1.0,3.0),72.0), ((2.0,1.0),37.0), ((1.0,1.0),32.0), ((2.0,2.0),26.0), ((3.0,2.0),19.0), ((3.0,3.0),49.0)),正確。

瓶頸可能在cartesian處。以後有條件了,會把大規模集群的結果貼上來看看。

矩陣冪(矩陣相乘)

題目描述 給定乙個n n的矩陣,求該矩陣的k次冪,即p k。第一行 兩個整數n 2 n 10 k 1 k 5 兩個數字之間用乙個空格隔開,含義如上所示。接下來有n行,每行n個正整數,其中,第i行第j個整數表示矩陣中第i行第j列的矩陣元素pij且 0 pij 10 另外,資料保證最後結果不會超過10 ...

CULA矩陣相乘和CUBLAS矩陣相乘

cula的矩陣相乘 culadevicedgemm n n n,m,k,alpha,b device,n,b k x n a device,k,a m x k beta,c device,n 上式表示 c a b的矩陣相乘方法,而且資料型別為double,也可以使用float型別資料的函式 cula...

tensorflow中向量與矩陣相乘

tensorflow學習的小白一枚。今天看到tensorflow中矩陣的乘法,看到有帖子說tensorflow中向量不能與矩陣直接相乘,不然會出錯。我就覺得很奇怪,tensorflow這麼流行的庫怎麼會出現這種弱智的問題呢?然後看了幾個帖子,怎麼解決這個問題的,看了半天,覺得太複雜了,並且他們寫錯了...