在DF

2016-07-29 64 views
0

計數兩次出現和共生我想兩個變量xy,我在一個Spark數據幀,看起來像這樣與計算mutual information(MI):在DF

scala> df.show() 
+---+---+ 
| x| y| 
+---+---+ 
| 0| DO| 
| 1| FR| 
| 0| MK| 
| 0| FR| 
| 0| RU| 
| 0| TN| 
| 0| TN| 
| 0| KW| 
| 1| RU| 
| 0| JP| 
| 0| US| 
| 0| CL| 
| 0| ES| 
| 0| KR| 
| 0| US| 
| 0| IT| 
| 0| SE| 
| 0| MX| 
| 0| CN| 
| 1| EE| 
+---+---+ 

在我的情況下, x恰好是事件是否發生(x = 1)或不是(x = 0),而y是國家代碼,但這些變量可能代表任何事物。爲了計算xy之間的MI我想有通過x, y雙以下三個附加列編組上述數據框:

  • x
  • y
  • 出現的次數出現的次數
  • x, y

出現在上面的短示例的數目,它看起來像

x, y, count_x, count_y, count_xy 
0, FR, 17, 2, 1 
1, FR, 3, 2, 1 
... 

然後,我只需要計算每個x, y對的互信息項並對它們進行求和。

到目前爲止,我已經能夠按x, y雙和骨料count(*)列,但我無法找到一個有效的方式來添加xy計數。我目前的解決方案是將DF轉換爲數組並手動計算出現次數和共同出現次數。它在y是一個國家時效果很好,但當y的基數變大時需要永久​​使用。任何建議,我怎麼能在更多Sparkish方式?

在此先感謝!

回答

1

我會去與RDDs,爲每個用例生成一個密鑰,按鍵計數並加入結果。這樣我就知道到底是什麼階段。

rdd.cache() // rdd is your data [x,y] 
val xCnt:RDD[Int, Int] = rdd.countByKey 
val yCnt:RDD[String, Int] = rdd.countByValue 
val xyCnt:RDD[(Int,String), Int] = rdd.map((x, y) => ((x,y), x,y)).countByKey 
val tmp = xCnt.cartsian(yCnt).map(((x, xCnt),(y, yCnt)) => ((x,y),xCnt,yCnt)) 
val miReady = tmp.join(xyCnt).map(((x,y), ((xCnt, yCnt), xyCnt)) => ((x,y), xCnt, yCnt, xyCnt)) 

另一種選擇是使用地圖分區,並簡單地工作在迭代和合並跨分區的決議。

1

也是Spark的新手,但我有一個想法該怎麼做。我不知道這是否是完美的解決方案,但我認爲分享這不會造成傷害。

我會做什麼可能是過濾器()的值1來創建一個數據框和過濾器()爲0值的第二個數據幀

你會得到這樣的事情

1數據幀

DO 1
DO 1
FR 1

在下一步驟i將GROUPBY(Y)

所以,你會得到的第一個數據幀

DO 1 1

FR 1

由於GroupedData https://spark.apache.org/docs/1.4.0/api/java/org/apache/spark/sql/GroupedData.html

這也有應每進行計數行的count()函數組。不幸的是,我現在沒有時間自己嘗試一下,但我仍然想嘗試和幫助。

編輯:請讓我知道這是否有幫助,否則我會刪除答案,讓其他人仍然看看這個!

+0

感謝您的回答。這個解決方案是我暫時使用的解決方案,但我不確定它是否會推廣到y的基數爲3或更大的情況。粗略地說,它包括明確地製作笛卡爾積(同時考慮'y'只能取兩個值)。我認爲@ z-star提出了一個更全面的答案。 但是,請不要刪除您的答案,它仍然有效,可能對其他用戶有用,其他用戶可能會幫助您改進。 –