【问题标题】:Get average length of values of a column (from a hive table) in spark along with data types获取 spark 中列(来自配置单元表)的值的平均长度以及数据类型
【发布时间】:2020-10-23 03:07:13
【问题描述】:

任务:获取表的数据类型(在 hive 中)以及每列值的平均长度。

我正在尝试使用 scala 在 spark 中完成上述任务。 首先我做到了
val table = spark.sql("desc table")
输出包含三列,col_name、datatype、comment。
然后,我尝试仅将列值作为逗号分隔的字符串获取。

val col_string = table.select("col_name").rdd.map(i => "avg(length(trim("+i(0).toString+")))").collect.mkString(", ")

现在,我可以在另一个查询中使用此字符串来获取所有列的平均长度,如下所示,但输出数据帧的列数与表一样多,我不知道如何将它与table 数据框。

val tbl_length = spark.sql("select " + col_string + " from schema.table")

我已经研究过转置第二个数据帧,这看起来效率不高,而且我作为 spark 和 scala 的初学者很难掌握。

我上面的方法是好的/有效的吗?如果有更好的方法请建议。 即使有更好的方法,您能否也请解释一下我如何加入两个这样的 row=>column 数据集。

输入表:
col1| col2| col3
交流| 123| 0
Defg| 23456| 0

预期输出
列名|数据类型|平均长度
col1|字符串| 3
col2|诠释| 4
col3|诠释| 1

【问题讨论】:

  • 分享一些示例ip和op。
  • @SathiyanS 添加了示例输入和预期输出。请立即检查。

标签: scala apache-spark hive


【解决方案1】:

试试这个-

  val table = spark.catalog.getTable("df")
    val df = spark.sql(s"select * from ${table.name}")
    df.show(false)
    /**
      * +---+----+
      * |id |name|
      * +---+----+
      * |1  |abc1|
      * |2  |abc2|
      * |3  |abc3|
      * +---+----+
      */
    val aggs = df.columns.map(f => avg(length(trim(col(f)))).as(f))
    val values = df.agg(aggs.head, aggs.tail: _*).head.getValuesMap[Double](df.columns).values.toSeq
    df.schema.map(sf => (sf.name, sf.dataType)).zip(values).map{ case ((name, dt), value) => (name, dt.simpleString, value)}
      .toDF("column_name", "data_type", "avg_length")
      .show(false)

    /**
      * +-----------+---------+----------+
      * |column_name|data_type|avg_length|
      * +-----------+---------+----------+
      * |id         |bigint   |1.0       |
      * |name       |string   |4.0       |
      * +-----------+---------+----------+
      */

【讨论】:

  • 感谢您的回答。它正在工作,尽管稍微解释一下会更好。例如第一行中的“df”实际上是“schema.table”。我有一个疑问,val df = spark.sql(s"select * from ${table.name}") 这不会将表的所有内容都放入内存吗?如果我的表中有数百万行,这会是一个有效的解决方案吗?请澄清。
  • val df = spark.sql(s"select * from ${table.name}") 由于 spark 的惰性,它永远不会将数据加载到内存中。当我们计算必须执行操作的所有列的平均长度时,数据将被加载。我相信这是满足您要求的最佳性能方式。如果有帮助,请随时接受 + 点赞
猜你喜欢
  • 1970-01-01
  • 2020-09-01
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
  • 2015-09-07
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
相关资源
最近更新 更多