获取 Spark 中列值的平均长度(来自 Hive 表)以及数据类型



>任务:获取表的数据类型(在配置单元中(和每列值的平均长度。

我正在尝试使用 scala 在 Spark 中完成上述任务。 首先,我做了
val table = spark.sql("desc table")
输出有三列,col_name,数据类型,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
Ac| 123| 0
Defg| 23456| 0

预期输出
column_name| data_type| avg_length
col1|字符串|3COL2|国际|4col3|国际|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       |
* +-----------+---------+----------+
*/

最新更新