如何在 Python 中排除 Spark 数据框中的多列
How to exclude multiple columns in Spark dataframe in Python
我发现 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
只需 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 中的理解速度明显快于
map
或 reduce
等方法
- Spark 2.x+ 支持
drop
中的多列。有关详细信息,请参阅 SPARK-11884 (Drop multiple columns in the DataFrame API) and SPARK-12204(在 SparkR 中为 DataFrame 实现 drop 方法)。
在 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'])
正确的做法是:
df.drop(*['col1', 'col2', 'col3'])
如果要删除多列,*
需要放在括号之外。
如果以上方法都不适合你,试试这个:
df.drop(col("col1")).drop(col("col2))
我的spark版本是3.1.2.
我发现 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
只需 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 中的理解速度明显快于
map
或reduce
等方法
- Spark 2.x+ 支持
drop
中的多列。有关详细信息,请参阅 SPARK-11884 (Drop multiple columns in the DataFrame API) and SPARK-12204(在 SparkR 中为 DataFrame 实现 drop 方法)。
在 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'])
正确的做法是:
df.drop(*['col1', 'col2', 'col3'])
如果要删除多列,*
需要放在括号之外。
如果以上方法都不适合你,试试这个:
df.drop(col("col1")).drop(col("col2))
我的spark版本是3.1.2.