복붙노트

[SCALA] 스칼라 스파크 : DataFrame에 Dataframe [벡터] 변환 방법 [F1 : 더블, ..., FN : 더블)]

SCALA

스칼라 스파크 : DataFrame에 Dataframe [벡터] 변환 방법 [F1 : 더블, ..., FN : 더블)]

난 그냥 ML 응용 프로그램 내 기능을 정상화 표준 스케일러를 사용했다. 내 벡터의 길이가 임의적 불구하고 스케일 기능을 선택한 후, 나는 복식의 dataframe이 다시 변환 할. 내가 사용하여 특정 3 개 기능을 위해 그것을 할 방법을 알고

myDF.map{case Row(v: Vector) => (v(0), v(1), v(2))}.toDF("f1", "f2", "f3")

하지만 기능의 임의의 한 금액을 초과 할 수 없습니다. 이 작업을 수행하는 쉬운 방법이 있습니까?

예:

val testDF = sc.parallelize(List(Vectors.dense(5D, 6D, 7D), Vectors.dense(8D, 9D, 10D), Vectors.dense(11D, 12D, 13D))).map(Tuple1(_)).toDF("scaledFeatures")
val myColumnNames = List("f1", "f2", "f3")
// val finalDF = DataFrame[f1: Double, f2: Double, f3: Double] 

편집하다

나는 dataframe을 만들 때 열 이름에 풀고,하지만 여전히 문제가 dataframe을 만드는 데 필요한 시퀀스에 벡터를 변환하는 데 방법을 발견 :

finalDF = testDF.map{case Row(v: Vector) => v.toArray.toSeq /* <= this errors */}.toDF(List("f1", "f2", "f3"): _*)

해결법

  1. ==============================

    1.한 가지 가능한 방법이 비슷한입니다

    한 가지 가능한 방법이 비슷한입니다

    import org.apache.spark.sql.functions.udf
    import org.apache.spark.mllib.linalg.Vector
    
    // Get size of the vector
    val n = testDF.first.getAs[org.apache.spark.mllib.linalg.Vector](0).size
    
    // Simple helper to convert vector to array<double> 
    val vecToSeq = udf((v: Vector) => v.toArray)
    
    // Prepare a list of columns to create
    val exprs = (0 until n).map(i => $"_tmp".getItem(i).alias(s"f$i"))
    
    testDF.select(vecToSeq($"scaledFeatures").alias("_tmp")).select(exprs:_*)
    

    당신이 열 목록을 알고 있다면이 조금 단순화 할 수 있습니다 선행 :

    val cols: Seq[String] = ???
    val exprs = cols.zipWithIndex.map{ case (c, i) => $"_tmp".getItem(i).alias(c) }
    

    PySpark를 사용하여 - 파이썬의 경우 해당 컬럼에 벡터를 분할하는 방법을 참조하십시오.

  2. ==============================

    2.며칠 전에 진화 대체 솔루션 : (이 불꽃에 병합되지 것만큼) 지금, 당신의 프로젝트에 VectorDisassembler를 가져옵니다

    며칠 전에 진화 대체 솔루션 : (이 불꽃에 병합되지 것만큼) 지금, 당신의 프로젝트에 VectorDisassembler를 가져옵니다

    import org.apache.spark.ml.feature.VectorAssembler
    import org.apache.spark.ml.linalg.Vectors
    
    val dataset = spark.createDataFrame(
      Seq((0, 1.2, 1.3), (1, 2.2, 2.3), (2, 3.2, 3.3))
    ).toDF("id", "val1", "val2")
    
    
    val assembler = new VectorAssembler()
      .setInputCols(Array("val1", "val2"))
      .setOutputCol("vectorCol")
    
    val output = assembler.transform(dataset)
    output.show()
    /*
    +---+----+----+---------+
    | id|val1|val2|vectorCol|
    +---+----+----+---------+
    |  0| 1.2| 1.3|[1.2,1.3]|
    |  1| 2.2| 2.3|[2.2,2.3]|
    |  2| 3.2| 3.3|[3.2,3.3]|
    +---+----+----+---------+*/
    
    val disassembler = new org.apache.spark.ml.feature.VectorDisassembler()
      .setInputCol("vectorCol")
    disassembler.transform(output).show()
    /*
    +---+----+----+---------+----+----+
    | id|val1|val2|vectorCol|val1|val2|
    +---+----+----+---------+----+----+
    |  0| 1.2| 1.3|[1.2,1.3]| 1.2| 1.3|
    |  1| 2.2| 2.3|[2.2,2.3]| 2.2| 2.3|
    |  2| 3.2| 3.3|[3.2,3.3]| 3.2| 3.3|
    +---+----+----+---------+----+----+*/
    
  3. ==============================

    3.VectorSlicer을 시도하십시오 :

    VectorSlicer을 시도하십시오 :

    import org.apache.spark.ml.feature.VectorAssembler
    import org.apache.spark.ml.linalg.Vectors
    
    val dataset = spark.createDataFrame(
      Seq((1, 0.2, 0.8), (2, 0.1, 0.9), (3, 0.3, 0.7))
    ).toDF("id", "negative_logit", "positive_logit")
    
    
    val assembler = new VectorAssembler()
      .setInputCols(Array("negative_logit", "positive_logit"))
      .setOutputCol("prediction")
    
    val output = assembler.transform(dataset)
    output.show()
    /*
    +---+--------------+--------------+----------+
    | id|negative_logit|positive_logit|prediction|
    +---+--------------+--------------+----------+
    |  1|           0.2|           0.8| [0.2,0.8]|
    |  2|           0.1|           0.9| [0.1,0.9]|
    |  3|           0.3|           0.7| [0.3,0.7]|
    +---+--------------+--------------+----------+
    */
    
    val slicer = new VectorSlicer()
    .setInputCol("prediction")
    .setIndices(Array(1))
    .setOutputCol("positive_prediction")
    
    val posi_output = slicer.transform(output)
    posi_output.show()
    
    /*
    +---+--------------+--------------+----------+-------------------+
    | id|negative_logit|positive_logit|prediction|positive_prediction|
    +---+--------------+--------------+----------+-------------------+
    |  1|           0.2|           0.8| [0.2,0.8]|              [0.8]|
    |  2|           0.1|           0.9| [0.1,0.9]|              [0.9]|
    |  3|           0.3|           0.7| [0.3,0.7]|              [0.7]|
    +---+--------------+--------------+----------+-------------------+
    */
    
  4. from https://stackoverflow.com/questions/38110038/spark-scala-how-to-convert-dataframevector-to-dataframef1double-fn-d by cc-by-sa and MIT license