如何有效地将DataFrame变成(列名->列值列表)的Map

时间:2018-12-17 10:33:08

标签: scala apache-spark dataframe apache-spark-sql rdd

我想要实现的是针对以下DataFrame:

-------------------------
| FOO   | BAR   | BAZ   |
| lorem | ipsum | dolor |
| sit   | amet  | dolor |
| lorem | lorem | dolor |
-------------------------

生成以下输出:

Map(
 FOO -> List("lorem", "sit"),
 BAR -> List("ipsum", "amet", "lorem"),
 BAZ -> List("dolor")
)

这是我提出的Scala代码:

val df = data.distinct

df.columns.map((key) => {
  val distinctValues = df
    .select(col(key))
    .collect
    .map(df => df.getString(0))
    .toList
    .distinct
  (key, distinctValues)
}).toMap

我已经尝试过使用RDD替代此代码,并且以某种方式使它们快30%,但问题仍然存在: 这一切都是极其无效的。

我正在针对托管仅1000行样本数据集的本地Cassandra在本地运行Spark,但是这些操作会产生大量日志,并且需要花费7秒钟以上的时间来完成。

我做错了什么,有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

您有一个名为collect_set的函数

if( array.indexOf(str) > -1 )
{
  // Do stuff!
}

答案 1 :(得分:-1)

识别列的唯一值

for (x<- df.columns)
{
df.select(x).groupBy(x).count
}

我认为使用“近似”可以使速度更快。

import org.apache.spark.sql.functions.approx_count_distinct
df.agg(approx_count_distinct("some_column"))

这是zero323的一篇不错的帖子,解释了此>>

How to count occurrences of each distinct value for every column in a dataframe?