Scala 因式分解火花柱

Scala 因式分解火花柱,scala,apache-spark,spark-dataframe,Scala,Apache Spark,Spark Dataframe,可以对Spark数据帧列进行因式分解吗?对于分解,我的意思是创建列中每个唯一值到相同ID的映射 例如,原始数据帧: +----------+----------------+--------------------+ | col1| col2| col3| +----------+----------------+--------------------+ |1473490929|4060600988513370|

可以对Spark数据帧列进行因式分解吗?对于分解,我的意思是创建列中每个唯一值到相同ID的映射

例如,原始数据帧:

+----------+----------------+--------------------+
|      col1|            col2|                col3|
+----------+----------------+--------------------+
|1473490929|4060600988513370|                   A|
|1473492972|4060600988513370|                   A|
|1473509764|4060600988513370|                   B|
|1473513432|4060600988513370|                   C|
|1473513432|4060600988513370|                   A|
+----------+----------------+--------------------+
到分解版本:

+----------+----------------+--------------------+
|      col1|            col2|                col3|
+----------+----------------+--------------------+
|1473490929|4060600988513370|                   0|
|1473492972|4060600988513370|                   0|
|1473509764|4060600988513370|                   1|
|1473513432|4060600988513370|                   2|
|1473513432|4060600988513370|                   0|
+----------+----------------+--------------------+
在scala中,这将是相当简单的,但由于Spark将其数据帧分布在节点上,我不知道如何保持
a->0,B->1,C->2
的映射

另外,假设数据帧相当大(GB),这意味着不可能将一整列加载到一台机器的内存中


可以这样做吗?

您可以使用
StringIndexer
将字母编码到索引中:

import org.apache.spark.ml.feature.StringIndexer

val indexer = new StringIndexer()
  .setInputCol("col3")
  .setOutputCol("col3Index")

val indexed = indexer.fit(df).transform(df)
indexed.show()

+----------+----------------+----+---------+
|      col1|            col2|col3|col3Index|
+----------+----------------+----+---------+
|1473490929|4060600988513370|   A|      0.0|
|1473492972|4060600988513370|   A|      0.0|
|1473509764|4060600988513370|   B|      1.0|
|1473513432|4060600988513370|   C|      2.0|
|1473513432|4060600988513370|   A|      0.0|
+----------+----------------+----+---------+
数据:

val df = spark.createDataFrame(Seq(
              (1473490929, "4060600988513370", "A"),
              (1473492972, "4060600988513370", "A"),  
              (1473509764, "4060600988513370", "B"),
              (1473513432, "4060600988513370", "C"),
              (1473513432, "4060600988513370", "A"))).toDF("col1", "col2", "col3")

您可以使用用户定义的函数

首先,创建所需的映射:

val updateFunction = udf {(x: String) =>
  x match {
    case "A" => 0
    case "B" => 1
    case "C" => 2
    case _ => 3
  }
}
现在,您只需将其应用于数据帧:

df.withColumn("col3", updateFunction(df.col("col3")))

假设有30多个值:)。维护这个会很痛苦。功能应该比这个好一点。这只是一个例子;)。我知道,但是如果所有的值都是手动指定的,那么维护起来还是很困难的。完美,就像一个符咒!完全忘记了spark mllib。