簡體   English   中英

使用Java將數組轉換為Spark DataFrame中的DenseVector

[英]Convert Array to DenseVector in Spark DataFrame using Java

我正在運行Spark 2.3。 我想將以下DataFrame中的列featuresArrayType轉換為DenseVector 我在Java中使用Spark。

+---+--------------------+
| id|            features|
+---+--------------------+
|  0|[4.191401, -1.793...|
| 10|[-0.5674514, -1.3...|
| 20|[0.735613, -0.026...|
| 30|[-0.030161237, 0....|
| 40|[-0.038345724, -0...|
+---+--------------------+

root
 |-- id: integer (nullable = false)
 |-- features: array (nullable = true)
 |    |-- element: float (containsNull = false)

我已經編寫了以下UDF但它似乎不起作用:

private static UDF1 toVector = new UDF1<Float[], Vector>() {

    private static final long serialVersionUID = 1L;

    @Override
    public Vector call(Float[] t1) throws Exception {

        double[] DoubleArray = new double[t1.length];
        for (int i = 0 ; i < t1.length; i++)
        {
            DoubleArray[i] = (double) t1[i];
        }   
    Vector vector = (org.apache.spark.mllib.linalg.Vector) Vectors.dense(DoubleArray);
    return vector;
    }
}

我希望提取以下特征作為矢量,以便可以對其進行聚類。

我也在注冊UDF,然后按如下方式進行調用:

spark.udf().register("toVector", (UserDefinedAggregateFunction) toVector);
df3 = df3.withColumn("featuresnew", callUDF("toVector", df3.col("feautres")));
df3.show();  

在運行此代碼段時,我面臨以下錯誤:

ReadProcessData $ 1無法強制轉換為org.apache.spark.sql.expressions。 UserDefinedAggregateFunction

問題出在如何在Spark中注冊udf 你不應該使用UserDefinedAggregateFunction這是不是一個udf而是udaf用於聚合。 相反,您應該做的是:

spark.udf().register("toVector", toVector, new VectorUDT());

然后使用注冊功能,使用:

df3.withColumn("featuresnew", callUDF("toVector",df3.col("feautres")));

udf本身應作如下稍微調整:

UDF1 toVector = new UDF1<Seq<Float>, Vector>(){

  public Vector call(Seq<Float> t1) throws Exception {

    List<Float> L = scala.collection.JavaConversions.seqAsJavaList(t1);
    double[] DoubleArray = new double[t1.length()]; 
    for (int i = 0 ; i < L.size(); i++) { 
      DoubleArray[i]=L.get(i); 
    } 
    return Vectors.dense(DoubleArray); 
  } 
};

請注意,在星火2.3+您可以創建一個階式的udf ,可以直接調用。 從這個答案

UserDefinedFunction toVector = udf(
  (Seq<Float> array) -> /* udf code or method to call */, new VectorUDT()
);

df3.withColumn("featuresnew", toVector.apply(col("feautres")));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM