如何在Python中使用Spark dataframe排除多个列

54

我发现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
4个回答

70
在PySpark 2.1.0中,drop方法支持多列操作

PySpark 2.0.2:

DataFrame.drop(col)

PySpark 2.1.0:

->

PySpark 2.1.0

DataFrame.drop(*cols)

例子:

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

或者使用*操作符作为

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

我有一个场景,在那里我正在使用。 - Rups N
11
为了明确起见,以防有些人看到这里时不清楚,在@Patrick编写的上面的DataFrame.drop(*cols)中,cols是一个Python列表在它前面放置星号将其转换为位置参数 - Mike Williamson

57

仅仅使用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
  • 第一种方法生成等效于物理计划的逻辑计划。在第二种情况下,它将被重写。
  • 最后,Python中的推导式比像mapreduce这样的方法要快得多
  • Spark 2.x+支持在drop中删除多个列。有关详细信息,请参见SPARK-11884 (在DataFrame API中删除多个列)和SPARK-12204 (在SparkR中实现DataFrame的drop方法)。

9

正确的做法是:

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

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

这并没有为这篇文章添加任何新信息。*解包在这个答案中展示,并在这个评论中进一步解释了语法。 - pault
你指向的答案对我无效:df.drop('col1', 'col2')是不正确的,列名必须在括号内,而*号需要位于括号外面。这就是为什么我发布了这篇帖子。 - Ceren
1
如果这个方法对你不起作用,那么你的错误可能出现在其他地方,因为 df.drop(*['col1', 'col2']) 在语法上等同于 df.drop('col1', 'col2') - pault
@pault,你是对的。不知为何,之前你的方法对我无效,但现在可以了。无论如何,如果您决定使用括号,*都是必需的,因此我认为将答案保留在这里作为可能的替代解决方案是公平的。谢谢。 - Ceren
@Ceren:如何使这些更改在数据框中发生?就像在Python中inplace=True一样,然后更改会反映在数据框中。注意到df.drop(*cols)返回新的数据框。 - Innovator-programmer

0
如果以上方法对您无效,请尝试以下方法:
df.drop(col("col1")).drop(col("col2))

我的 Spark 版本是 3.1.2。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接