【问题标题】:Dropping multiple columns from Spark dataframe by Iterating through the columns from a Scala List of Column names通过迭代 Scala 列名列表中的列,从 Spark 数据帧中删除多列
【发布时间】:2017-02-08 17:59:06
【问题描述】:

我有一个包含 400 列左右的数据框,我想根据我的要求删除 100 列。 所以我创建了一个包含 100 个列名的 Scala 列表。 然后我想遍历一个 for 循环以在每个 for 循环迭代中实际删除列。

下面是代码。

final val dropList: List[String] = List("Col1","Col2",...."Col100”)

def drpColsfunc(inputDF: DataFrame): DataFrame = { 
    for (i <- 0 to dropList.length - 1) {
        val returnDF = inputDF.drop(dropList(i))
    }
    return returnDF
}

val test_df = drpColsfunc(input_dataframe) 

test_df.show(5)

【问题讨论】:

  • 我收到无法解析“returnDF”的编译错误。谁能帮忙解决这个问题。
  • 请让问题自成一体。您为什么将部分问题放在 cmets 中? How do I ask a good question?
  • edit您的问题以及您在 cmets 中添加的其他信息!
  • @Martin 和 Eliasah-- 完成问题中的更改。谢谢
  • 我在上面的代码中遇到的问题是,我得到一个编译错误,“无法解析'returnDF'”。谁能帮忙解决这个问题。

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


【解决方案1】:

如果您只想做比删除多个命名列更复杂的操作,而不是按特定条件选择它们,您可以简单地执行以下操作:

df.drop("colA", "colB", "colC")

【讨论】:

    【解决方案2】:

    答案:

    val colsToRemove = Seq("colA", "colB", "colC", etc) 
    
    val filteredDF = df.select(df.columns .filter(colName => !colsToRemove.contains(colName)) .map(colName => new Column(colName)): _*) 
    

    【讨论】:

    • 工作正常。能否请您在这里详细说明“_*”的含义?
    • on : _* :如果你知道 python,它类似于你放在列表前面的解包一元运算符 *。上面: _* 之前的表达式是Column 的序列(更准确地说是Array[Column]),但是select 的(一种形式)需要Column 的可变参数字段,即。可变数量的Column 对象。例如:alvinalexander.com/scala/…
    • df.drop(colsToRemove : _*) 这是一个更简单|更清洁的解决方案。
    【解决方案3】:

    这应该可以正常工作:

    val dropList : List[String]  |
    val df : DataFrame  |
    val test_df = df.drop(dropList : _*) 
    

    【讨论】:

      【解决方案4】:

      你可以这样做,

      def dropColumns(inputDF: DataFrame, dropList: List[String]): DataFrame = 
          dropList.foldLeft(inputDF)((df, col) => df.drop(col))
      

      它将返回DataFrame,但不包含dropList 中传递的列。

      作为一个例子(幕后发生的事情),让我这样说吧。

      scala> val list = List(0, 1, 2, 3, 4, 5, 6, 7)
      list: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7)
      
      scala> val removeThese = List(0, 2, 3)
      removeThese: List[Int] = List(0, 2, 3)
      
      scala> removeThese.foldLeft(list)((l, r) => l.filterNot(_ == r))
      res2: List[Int] = List(1, 4, 5, 6, 7)
      

      返回的列表(在我们的例子中,将其映射到您的 DataFrame)是最新过滤的。每次折叠后,最新的被传递给下一个函数(_, _) =&gt; _

      【讨论】:

        【解决方案5】:

        您可以使用删除操作删除多个列。如果列表中有需要删除的列名,则可以在列列表变量之后使用:_* 传递它,它将删除您传递的列表中的所有列。

        斯卡拉:

        val df = Seq(("One","Two","Three"),("One","Two","Three"),("One","Two","Three")).toDF("Name","Name1","Name2")
        val columnstoDrop = List("Name","Name1")
        val df1 = df.drop(columnstoDrop:_*)
        

        Python: 在 python 中,你可以使用 * 操作符来做同样的事情。

        data = [("One", "Two","Three"), ("One", "Two","Three"), ("One", "Two","Three")]
        columns = ["Name","Name1","Name2"]
        df = spark.sparkContext.parallelize(data).toDF(columns)
        columnstoDrop = ["Name","Name1"]
        df1 = df.drop(*columnstoDrop)
        

        现在在 df1 中,您将获得只有一列的数据框,即 Name2。

        【讨论】:

          猜你喜欢
          • 2021-12-07
          • 2011-09-23
          • 2018-09-26
          • 2019-07-02
          • 2021-06-02
          • 2011-03-18
          • 1970-01-01
          • 2020-05-10
          • 2021-08-16
          相关资源
          最近更新 更多