我正在使用Spark 1.6.1。让我们说我的数据框架如下:
+------------+-----+----+
|categoryName|catA |catB|
+------------+-----+----+
| catA |0.25 |0.75|
| catB |0.5 |0.5 |
+------------+-----+----+
categoryName
具有字符串类型,cat*
为Double。我想添加一个列,该列将包含名称位于categoryName
列中的列的值:
+------------+-----+----+-------+
|categoryName|catA |catB| score |
+------------+-----+----+-------+
| catA |0.25 |0.75| 0.25 | ('score' has value from column name 'catA')
| catB |0.5 |0.7 | 0.7 | ('score' value from column name 'catB')
+------------+-----+----+-------+
我需要这样的提取到稍后的计算。有什么想法吗?
重要提示:我不知道类别列的名称。解决方案需要是动态的。
答案 0 :(得分:3)
Spark 2.0 : 您可以通过创建一个包含categroyName - >地图的临时列来执行此操作(对于任意数量的类别列)。 categoryValue,然后从中进行选择:
// sequence of any number of category columns
val catCols = input.columns.filterNot(_ == "categoryName")
// create a map of category -> value, and then select from that map using categoryName:
input
.withColumn("asMap", map(catCols.flatMap(c => Seq(lit(c), col(c))): _*))
.withColumn("score", $"asMap".apply($"categoryName"))
.drop("asMap")
Spark 1.6 :类似的想法,但使用数组和UDF从中进行选择:
// sequence of any number of category columns
val catCols = input.columns.filterNot(_ == "categoryName")
// UDF to select from array by index of colName in catCols
val getByColName = udf[Double, String, mutable.WrappedArray[Double]] {
case (colName, colValues) =>
val index = catCols.zipWithIndex.find(_._1 == colName).map(_._2)
index.map(colValues.apply).getOrElse(0.0)
}
// create an array of category values and select from it using UDF:
input
.withColumn("asArray", array(catCols.map(col): _*))
.withColumn("score", getByColName($"categoryName", $"asArray"))
.drop("asArray")
答案 1 :(得分:1)
您有几种选择: