将相同的函数应用于spark数据帧行

时间:2015-12-02 08:22:33

标签: apache-spark apache-spark-sql

我有数据框,其中我有大约1000个(可变)列。

我想将所有值都设为大写。

这是我想到的方法,你能否提出这是否是最佳方式。

  • 采取行
  • 在数组中查找架构并存储,并查找有多少字段。
  • 映射数据框中的每一行以及数组中元素数量的限制
  • 将函数应用于大写每个字段并返回行

2 个答案:

答案 0 :(得分:26)

如果您只是想对所有列应用相同的功能,那么这样就足够了:

import org.apache.spark.sql.functions.{col, upper}

val df = sc.parallelize(
  Seq(("a", "B", "c"), ("D", "e", "F"))).toDF("x", "y", "z")
df.select(df.columns.map(c => upper(col(c)).alias(c)): _*).show

// +---+---+---+
// |  x|  y|  z|
// +---+---+---+
// |  A|  B|  C|
// |  D|  E|  F|
// +---+---+---+

或在Python中

from pyspark.sql.functions import col, upper

df = sc.parallelize([("a", "B", "c"), ("D", "e", "F")]).toDF(("x", "y", "z"))
df.select(*(upper(col(c)).alias(c) for c in df.columns)).show()

##  +---+---+---+
##  |  x|  y|  z|
##  +---+---+---+
##  |  A|  B|  C|
##  |  D|  E|  F|
##  +---+---+---+

另请参阅:SparkSQL: apply aggregate functions to a list of column

答案 1 :(得分:1)

我需要做类似的事情,但必须编写自己的函数将数据帧中的空字符串转换为null。这就是我所做的。

import org.apache.spark.sql.functions.{col, udf} 
import spark.implicits._ 

def emptyToNull(_str: String): Option[String] = {
  _str match {
    case d if (_str == null || _str.trim.isEmpty) => None
    case _ => Some(_str)
  }
}
val emptyToNullUdf = udf(emptyToNull(_: String))

val df = Seq(("a", "B", "c"), ("D", "e ", ""), ("", "", null)).toDF("x", "y", "z")
df.select(df.columns.map(c => emptyToNullUdf(col(c)).alias(c)): _*).show

+----+----+----+
|   x|   y|   z|
+----+----+----+
|   a|   B|   c|
|   D|  e |null|
|null|null|null|
+----+----+----+

这是使用选项而不是null的emptyToNull的更完善的功能。

def emptyToNull(_str: String): Option[String] = Option(_str) match {
  case ret @ Some(s) if (s.trim.nonEmpty) => ret
  case _ => None
}