2016-10-01 86 views
0

我有一個DataFrame [SparseVector]從Spark中的ml庫中的HashingTF獲得。下面是我的架構:如何從Spark中的Dataframe [SparseVector]獲取所有非零值?

root 
|-- docId: string (nullable = true) 
|-- docNGrams: array (nullable = true) 
| |-- element: string (containsNull = true) 
|-- HashedNGrams: vector (nullable = true) 

HashedNGrams被2^31的稀疏矢量 - 1 = 2147483647號的特徵(最大)。 HashedNGrams的一個例子是:

[doc/00000.txt,(2147483647,[70921,235056,....],[1.0,2.0,...]) 
[doc/00001.txt,(2147483647,[6067499,8758008,....],[1.0,1.0,...]) 
...... 
...... 

我想要的是得到公正的價值觀:從這個數據幀

70921,235056 
6067499,8758008 
..... , ... 

到Vector,列表[INT],什麼的,這樣做的一些操作數據。我到目前爲止試過的是: 1)嘗試將其轉換爲密集的矢量,但它給了我一個超出限制虛擬機異常 2)嘗試了我從這裏找到的所有可能的解決方案,但根本不缺乏!他們都給我一個錯誤。 3)即使將它保存在一個文件中,然後試圖將這些值作爲一個字符串(還沒有完成,但我覺得這是非常錯誤的方法)。

請幫忙!

+0

你的情況'70921,235056'是索引而不是值。 – zero323

回答

0

您可以使用用戶定義函數(UDF)是一種把SparseVector到值的數組 - 這裏是如何添加一個名爲values這些數組新列:

import org.apache.spark.sql.functions._ 

val valuesOnly = udf { s: SparseVector => s.values } 
val result = df.withColumn("values", valuesOnly(col("HashedNGrams"))) 

UPDATE:如前所述通過@ zero323,OP的確是在指數之後而不是數值。正如所評論的,這可以通過在UDF中使用s.indices而不是s.values來輕鬆實現。

+0

非常感謝!通過這兩個答案的組合(你的和@ zero323)我得到了我想要的。我正在尋找那個時代! 'import org.apache.spark.sql.functions._ val valuesOnly = udf {s:SparseVector => s.indices} val result = df.withColumn(「values」,valuesOnly(col(「HashedNGrams」)) )' – Spartan

+0

很高興幫助 - 實際上我沒有注意到這個例子中的期望值實際上是指數。如果您贊成/接受讓其他用戶知道該問題得到解答的答案,將會有所幫助。 –

+0

我做到了!但它給了我:記錄下不到15聲望的投票,但不會改變顯示後分數的公示。 – Spartan

相關問題