【问题标题】:In spark iterate through each column and find the max length在火花中遍历每一列并找到最大长度
【发布时间】:2019-06-13 06:26:42
【问题描述】:

我是 spark scala 的新手,我遇到以下情况 我在集群上有一个表“TEST_TABLE”(可以是配置单元表) 我正在将其转换为数据框 如:

scala> val testDF = spark.sql("select * from TEST_TABLE limit 10")

现在DF可以被视为

scala> testDF.show()

COL1|COL2|COL3  
----------------
abc|abcd|abcdef 
a|BCBDFG|qddfde 
MN|1234B678|sd

我想要一个像下面这样的输出

COLUMN_NAME|MAX_LENGTH
       COL1|3
       COL2|8
       COL3|6

在 spark scala 中这样做是否可行?

【问题讨论】:

    标签: scala apache-spark aggregation maxlength


    【解决方案1】:

    简单明了:

    import org.apache.spark.sql.functions._
    
    val df = spark.table("TEST_TABLE")
    df.select(df.columns.map(c => max(length(col(c)))): _*)
    

    【讨论】:

    • 你能把它也转换成 PySpark 吗?谢谢
    【解决方案2】:

    您可以通过以下方式尝试:

    import org.apache.spark.sql.functions.{length, max}
    import spark.implicits._
    
    val df = Seq(("abc","abcd","abcdef"),
              ("a","BCBDFG","qddfde"),
              ("MN","1234B678","sd"),
              (null,"","sd")).toDF("COL1","COL2","COL3")
    df.cache()
    val output = df.columns.map(c => (c, df.agg(max(length(df(s"$c")))).as[Int].first())).toSeq.toDF("COLUMN_NAME", "MAX_LENGTH")
            +-----------+----------+
            |COLUMN_NAME|MAX_LENGTH|
            +-----------+----------+
            |       COL1|         3|
            |       COL2|         8|
            |       COL3|         6|
            +-----------+----------+
    

    我认为缓存输入数据帧df 以加快计算速度是个好主意。

    【讨论】:

    • 很好的解决方案,但是,我的实际数据有空和空白,所以“.as[Int]”会抛出错误,如果我删除“.as[Int]”,那么它会要求“编码器”错误:java.lang.UnsupportedOperationException:没有为 org.apache.spark.sql.Row 找到编码器 - 字段(类:“org.apache.spark.sql.Row”,名称:“_2”) - 根类:“scala .Tuple2"
    • 谢谢,我正在尝试重新生成您面临的问题。我已经编辑了我的答案,我已经插入了空和空白的行,但它没有显示任何错误。您能否提供示例行以便我可以重新生成问题? .
    • 嗨,我只是将 .as[Int] 更改为 .as[String] ,现在可以使用
    • 如果对您有帮助,您能接受答案吗? :)
    【解决方案3】:

    这是另一种获取垂直列名报告的方法

    scala> val df = Seq(("abc","abcd","abcdef"),("a","BCBDFG","qddfde"),("MN","1234B678","sd")).toDF("COL1","COL2","COL3")
    df: org.apache.spark.sql.DataFrame = [COL1: string, COL2: string ... 1 more field]
    
    scala> df.show(false)
    +----+--------+------+
    |COL1|COL2    |COL3  |
    +----+--------+------+
    |abc |abcd    |abcdef|
    |a   |BCBDFG  |qddfde|
    |MN  |1234B678|sd    |
    +----+--------+------+
    
    scala> val columns = df.columns
    columns: Array[String] = Array(COL1, COL2, COL3)
    
    scala> val df2 = columns.foldLeft(df) { (acc,x) => acc.withColumn(x,length(col(x))) }
    df2: org.apache.spark.sql.DataFrame = [COL1: int, COL2: int ... 1 more field]
    
    scala> df2.select( columns.map(x => max(col(x))):_* ).show(false)
    +---------+---------+---------+
    |max(COL1)|max(COL2)|max(COL3)|
    +---------+---------+---------+
    |3        |8        |6        |
    +---------+---------+---------+
    
    
    scala> df3.flatMap( r => { (0 until r.length).map( i => (columns(i),r.getInt(i)) ) } ).show(false)
    +----+---+
    |_1  |_2 |
    +----+---+
    |COL1|3  |
    |COL2|8  |
    |COL3|6  |
    +----+---+
    
    
    scala>
    

    要将结果放入 Scala 集合中,例如 Map()

    scala> val result = df3.flatMap( r => { (0 until r.length).map( i => (columns(i),r.getInt(i)) ) } ).as[(String,Int)].collect.toMap
    result: scala.collection.immutable.Map[String,Int] = Map(COL1 -> 3, COL2 -> 8, COL3 -> 6)
    
    scala> result
    res47: scala.collection.immutable.Map[String,Int] = Map(COL1 -> 3, COL2 -> 8, COL3 -> 6)
    
    scala>
    

    【讨论】:

      猜你喜欢
      • 2023-02-17
      • 1970-01-01
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 2018-04-11
      • 2014-12-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多