【问题标题】:How to exclude multiple columns in Spark dataframe in Python如何在 Python 中排除 Spark 数据框中的多列
【发布时间】:2016-06-11 00:18:27
【问题描述】:

我发现 PySpark 有一个名为 drop 的方法,但它似乎一次只能删除一列。关于如何同时删除多列的任何想法?

df.drop(['col1','col2'])
TypeError                                 Traceback (most recent call last)
<ipython-input-96-653b0465e457> in <module>()
----> 1 selectedMachineView = machineView.drop([['GpuName','GPU1_TwoPartHwID']])

/usr/hdp/current/spark-client/python/pyspark/sql/dataframe.pyc in drop(self, col)
   1257             jdf = self._jdf.drop(col._jc)
   1258         else:
-> 1259             raise TypeError("col should be a string or a Column")
   1260         return DataFrame(jdf, self.sql_ctx)
   1261 

TypeError: col should be a string or a Column

【问题讨论】:

    标签: apache-spark dataframe pyspark apache-spark-sql


    【解决方案1】:

    在 PySpark 2.1.0 方法中 drop supports multiple columns:

    PySpark 2.0.2:

    DataFrame.drop(col)
    

    PySpark 2.1.0:

    DataFrame.drop(*cols)
    

    例子:

    df.drop('col1', 'col2')
    

    或使用* 运算符作为

    df.drop(*['col1', 'col2'])
    

    【讨论】:

    【解决方案2】:

    只需select:

    df.select([c for c in df.columns if c not in {'GpuName','GPU1_TwoPartHwID'}])
    

    或者如果你真的想使用drop,那么reduce 应该可以解决问题:

    from functools import reduce
    from pyspark.sql import DataFrame
    
    reduce(DataFrame.drop, ['GpuName','GPU1_TwoPartHwID'], df)
    

    注意:

    (执行时间的差异):

    在数据处理时间方面应该没有区别。虽然这些方法生成不同的逻辑计划,但物理计划完全相同。

    但是,当我们分析驱动端代码时,情况有所不同:

    • 第一种方法只调用一次 JVM,而第二种方法必须为必须排除的每一列调用 JVM
    • 第一种方法生成逻辑计划,相当于物理计划。在第二种情况下,它被重写。
    • finally Python 中的理解比map 或reduce 等方法快得多
    • Spark 2.x+ 支持drop 中的多列。请参阅SPARK-11884(在 DataFrame API 中删除多个列)和SPARK-12204(在 SparkR 中为 DataFrame 实现删除方法)了解详情。

    【讨论】:

      【解决方案3】:

      正确的做法是:

      df.drop(*['col1', 'col2', 'col3'])
      

      如果要删除多列,* 需要放在括号之外。

      【讨论】:

      • 这不会向这篇文章添加任何新信息。* 解包显示在this answer 中,并在this comment 中进一步解释语法
      • 您指向的答案对我不起作用: df.drop('col1', 'col2') 不正确,列必须在括号内,* 必须在括号外.这就是我发布的原因。
      • 如果它不适合你,你的错误就在其他地方,因为df.drop(*['col1', 'col2']) 在语法上等同于df.drop('col1', 'col2')
      • @pault 你是对的。出于某种原因,您的方法之前对我不起作用,但现在可以了。无论如何,如果您决定使用括号,* 是必要的,所以我认为将答案保留在这里作为潜在的替代解决方案是公平的。谢谢。
      • @Ceren:如何使这些更改发生在数据框中?就像它在 python inplace=True 中所做的那样,然后更改会反映在数据框中。正如所注意到的那样 df.drop(*cols) 返回新的数据帧。
      【解决方案4】:

      如果以上都不适合你,试试这个:

      df.drop(col("col1")).drop(col("col2))
      

      我的 spark 版本是 3.1.2。

      【讨论】:

        猜你喜欢
        • 2018-03-28
        • 1970-01-01
        • 2018-11-13
        • 1970-01-01
        • 2022-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多