基于apachespark和scala的数据预处理

基于apachespark和scala的数据预处理,scala,apache-spark,rdd,Scala,Apache Spark,Rdd,我对spark和scala非常陌生,因此我对使用spark进行数据预处理和使用RDD有一些疑问。 我正在做一个小项目,我想用spark实现一个机器学习系统。我认为使用算法是可以的,但是我在预处理数据方面有问题。 我有一个数据集,有30列,大约一百万行。但为了简单起见,假设我有以下数据集(csv文件): 在spark中加载数据后,我想执行以下步骤: 删除以“\u txt”结尾的所有列 过滤掉columnB为空的所有行(我已经解决了这个问题) 删除超过9个级别的列(此处为columnA) 所以我对问

我对spark和scala非常陌生,因此我对使用spark进行数据预处理和使用RDD有一些疑问。 我正在做一个小项目,我想用spark实现一个机器学习系统。我认为使用算法是可以的,但是我在预处理数据方面有问题。 我有一个数据集,有30列,大约一百万行。但为了简单起见,假设我有以下数据集(csv文件):

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

  • 删除以“\u txt”结尾的所有列
  • 过滤掉columnB为空的所有行(我已经解决了这个问题)
  • 删除超过9个级别的列(此处为columnA)
  • 所以我对问题1有问题。三,。 我知道我不能删除列,所以我必须创建一个新的rdd,但是如果没有某些列,我怎么做呢? 目前,我正在加载csv文件,spark中没有标题,但对于我的任务,我需要。是否建议在单独的rdd中加载标题?但是我如何与rdd交互以找到正确的列呢? 对不起,我知道很多问题,但我仍然在开始,并试图学习。 谢谢并致以最良好的祝愿,
    Chris

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

    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
        })
    

    如果加载时没有标题,则可以使用从自动指定的标题到实际标题的映射来执行相同的操作

    如果我是“手工”完成的,我会创建一个RDD,调用
    。使用(1)
    来获取主文件中的标题,对标题进行任何需要的处理/并行化,然后删除第一行以获取RDD中的数据。非常感谢您的回答!我会在接下来的几天内尝试。为什么要折叠而不是过滤?@dskrvk你是说像
    .filter(…).foreach(col=>df=df.drop(col))
    ?我想这只是一个参考透明度和个人品味的问题。
    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
        })