因式分解Spark列

问题描述:

是否可以分解Spark数据帧列?因式分解我的意思是创建列中每个唯一值到同一个ID的映射。因式分解Spark列

为例,原来的数据帧:

+----------+----------------+--------------------+ 
|  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| 
+----------+----------------+--------------------+ 

斯卡拉它本身是相当简单的,但由于星火分配它dataframes在节点我不是确定如何保持A->0, B->1, C->2的映射。

此外,假设数据帧非常大(千兆字节),这意味着将单个机器的整个列加载到内存中可能是不可能的。

可以这样做吗?

您可以使用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") 
+0

完美的,就像一个魅力!完全忘了spark-mllib。 – Tim

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

首先创建你所需要的映射:

val updateFunction = udf {(x: String) => 
    x match { 
    case "A" => 0 
    case "B" => 1 
    case "C" => 2 
    case _ => 3 
    } 
} 

而现在你只需要把它应用到你的DataFrame

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

想象一下有30多个值:)。这将是一个地狱,以维持这一点。 – Tim

+0

功能应该比这个好一点。这只是一个例子;)。 –

+0

我知道,但如果所有的值都是手动指定的,仍然很难保持。 – Tim