使用Spark过滤大型数据集中的列

时间:2015-09-08 14:30:03

标签: scala apache-spark bigdata

我的数据集是1,000,000行,约390,000列。这些字段都是二进制的,0或1.数据非常稀疏。

我一直在使用Spark来处理这些数据。我目前的任务是过滤数据 - 我只想要预先选择的1000列数据。这是我用来完成此任务的当前代码:

val result = bigdata.map(_.zipWithIndex.filter{case (value, index) => selectedColumns.contains(index)})

bigdata只是RDD[Array[Int]]

但是,此代码需要相当长的时间才能运行。我确信这是一种更有效的方法来过滤我的数据集,而这些数据集并不涉及分别进入和过滤每一行。是否会将我的数据加载到DataFrame中,并通过DataFrame API对其进行操作,从而使事情变得更快/更容易?我应该查看基于列存储的数据库吗?

2 个答案:

答案 0 :(得分:2)

您可以从提高过滤效率开始。请注意:

  • 您的RDD包含Array[Int]。这意味着您可以在 O(1)时间
  • 中访问每一行的第n个元素
  • #selectedColumns<< #columns

考虑到这两个事实,显而易见的是迭代每一行的所有元素而不提contains次调用是没有意义的。相反,您只需map而不是selectedColumns

// Optional if selectedColumns are not ordered
val orderedSelectedColumns = selectedColumns.toList.sorted.toArray
rdd.map(row => selectedColumns.map(row))

比较时间复杂度:

  1. zipWithIndex + filter(假设contains O(1)时最佳情况) - O(#rows *#columns)
  2. map - O(#rows * #selectedColumns)

答案 1 :(得分:1)

加速执行的最简单方法是将其与partitionBy并行化:

row_number()

foreachPartition会收到一个迭代器,您可以在其上进行映射和过滤。

numPartitions是一个val,您可以使用所需的并行分区数量来设置。