scala - Spark 计数大量列

标签 scala dataframe apache-spark

不久前遇到了这个问题,我认为应该有一个更好/更有效的方法来做到这一点:

我有一个大约有 70k 列和大约 10k 行的 DF。我基本上想根据行的值获取每列的计数。

df.columns.map( c => df.where(column(c)===1).count )

这适用于少量列,但在这种情况下,大量列会导致该过程需要几个小时,并且似乎要迭代每一列并查询数据。

我可以做哪些优化来更快地获得结果?

最佳答案

您可以将每一列的值替换为 10,具体取决于列先前的值是否匹配条件,然后在一次聚合中对每一列求和。之后,您可以收集结果数据帧的唯一行并将其设为数组。

所以代码如下:

import org.apache.spark.sql.functions.{col, lit, sum, when}

val aggregation_columns = df.columns.map(c => sum(col(c)))

df
  .columns
  .foldLeft(df)((acc, elem) => acc.withColumn(elem, when(col(elem) === 1, lit(1)).otherwise(lit(0))))
  .agg(aggregation_columns.head, aggregation_columns.tail: _*)
  .collect()
  .flatMap(row => df.columns.indices.map(i => row.getLong(i))

关于scala - Spark 计数大量列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69304509/

相关文章:

hadoop - 如何让 Spark 忽略丢失的输入文件?

scala - Flink 可以与 Kotlin 一起使用吗?

arrays - 什么时候应该使用Scala的Array而不是其他集合之一?

python - 两个 Pandas 数据框的联合

python - 指定 pandas 聚合函数的参数

java - Java 中的 Scala 方法重写

scala - Play 2.4 Scaldi WS 测试

scala - 为什么我的项目没有 build.sbt 文件?

python - 根据年份和儒略日在 pandas 中创建日期时间

scala - 使用 Scala 在 Spark 中进行 ETL 处理