如何在Spark Scala中迭代Dataframe中的每一列

时间:2017-06-23 21:17:54

标签: scala apache-spark dataframe bigdata

假设我有一个包含多列的数据框,我想迭代每一列,进行一些计算并更新该列。有没有好办法呢?

2 个答案:

答案 0 :(得分:3)

<强>更新 在下面的例子中,我有一个带有两个整数列c1和c2的数据帧。每列的值除以其列的总和。

import org.apache.spark.sql.expressions.Window
val df = Seq((1,15), (2,20), (3,30)).toDF("c1","c2")
val result = df.columns.foldLeft(df)((acc, colname) => acc.withColumn(colname, sum(acc(colname)).over(Window.orderBy(lit(1)))/acc(colname)))

<强>输出

scala> result.show()
+---+------------------+
| c1|                c2|
+---+------------------+
|6.0| 4.333333333333333|
|3.0|              3.25|
|2.0|2.1666666666666665|
+---+------------------+

答案 1 :(得分:2)

@ rogue-one已经回答了您的疑问,您只需修改答案即可满足您的要求。

以下是不使用Window功能的解决方案。

val df = List(
  (2, 28),
  (1, 21),
  (7, 42)
).toDF("col1", "col2")

您的输入dataframe应该是

+----+----+
|col1|col2|
+----+----+
|2   |28  |
|1   |21  |
|7   |42  |
+----+----+

现在应用columnValue/sumOfColumnValues执行

val columnsModify = df.columns.map(col).map(colName => {
  val total = df.select(sum(colName)).first().get(0)
  colName/total as(s"${colName}")
})

df.select(columnsModify: _*).show(false)

你应该输出

+----+-------------------+
|col1|col2               |
+----+-------------------+
|0.2 |0.3076923076923077 |
|0.1 |0.23076923076923078|
|0.7 |0.46153846153846156|
+----+-------------------+