使用apache spark和scala进行数据预处理

时间:2015-07-21 19:06:44

标签: scala apache-spark rdd

我对spark和scala很新,因此我有一些关于使用spark进行数据预处理和使用rdds的问题。 我正在做一个小项目,我想用火花来实现一个机器学习系统。我认为使用算法是可以的,但我在预处理数据时遇到了问题。 我有一个包含30列和大约一百万行的数据集。但为简单起见,我假设我有以下数据集(csv-file):

columnA, columnB, column_txt, label
1      , a      , abc       , 0
2      ,        , abc       , 0
3      , b      , abc       , 1
4      , b      , abc       , 1
5      , a      , abc       , 0
6      ,        , abc       , 0
7      , c      , abc       , 1
8      , a      , abc       , 1
9      , b      , abc       , 1
10     , c      , abc       , 0

在spark中加载数据后,我想执行以下步骤:

  1. 删除所有以" _txt"
  2. 结尾的列
  3. 过滤掉columnB为空的所有行(我已经知道了)
  4. 删除超过9个级别的列(此处为columnA)
  5. 所以我遇到问题1和3的问题。 我知道我不能删除列,所以我必须创建一个新的rdd,但是如果没有某些列,我该怎么办呢? 现在我在加载csv文件时没有头文件,但我需要完成我的任务。是否可以在单独的rdd中加载标题?但是,我如何与该rdd进行交互以找到正确的列呢? 对不起,我知道很多问题,但我还在开始并尝试学习。 谢谢和最好的问候, 克里斯

1 个答案:

答案 0 :(得分:1)

假设数据框加载了标题并且结构是平的:

val df = sqlContext.
    read.
    format("com.databricks.spark.csv").
    option("header", "true").
    load("data.csv")

这样的事情应该有效:

import org.apache.spark.sql.DataFrame

def moreThan9(df: DataFrame, col: String) = {
    df.agg(countDistinct(col)).first()(0) match {
        case x: Long => x > 9L
        case _ => false
    }
}

val newDf = df.
    schema. //  Extract schema
    toArray. // Convert to array
    map(_.name). // Map to names
    foldLeft(df)((df: DataFrame, col: String) => {
        if (col.endsWith("_txt") | moreThan9(df, col)) df.drop(col) else df
    })

如果它是在没有标题的情况下加载的,那么你可以使用从自动分配的映射到实际的映射来做同样的事情。