ChatGPT解决这个技术问题 Extra ChatGPT

如何删除pyspark数据框中的列

>>> a
DataFrame[id: bigint, julian_date: string, user_id: bigint]
>>> b
DataFrame[id: bigint, quan_created_money: decimal(10,0), quan_created_cnt: bigint]
>>> a.join(b, a.id==b.id, 'outer')
DataFrame[id: bigint, julian_date: string, user_id: bigint, id: bigint, quan_created_money: decimal(10,0), quan_created_cnt: bigint]

有两个 id: bigint,我想删除一个。我能怎么做?


q
qwr

阅读 Spark 文档,我发现了一个更简单的解决方案。

从 spark 1.4 版开始,有一个函数 drop(col) 可以在数据帧上的 pyspark 中使用。

您可以通过两种方式使用它

df.drop('年龄') df.drop(df.age)

Pyspark Documentation - Drop


当数据量很大时,collect() 可能会导致堆空间错误。您还可以创建一个新的数据框,通过 ndf = df.drop('age') 删除额外的字段
绝对没有理由为此操作使用 collect 所以我从这个答案中删除了它
C
Clock Slave

添加到@Patrick 的答案,您可以使用以下内容删除多列

columns_to_drop = ['id', 'id_copy']
df = df.drop(*columns_to_drop)

我不得不将删除结果重新分配回数据框: df = df.drop(*columns_to_drop)
请注意,如果该列不存在,您将不会收到错误
删除列并使用 .show() 后,我收到一条错误消息 TreeNodeException: Binding attribute, tree: _gen_alias_34#34
*columns_to_drop 中的星号 * 是什么意思?
* 用于解包列表。 (*[a,b,c]) 变为 (a,b,c)
H
Haroldo Gondim

一个简单的方法是用户“select”并意识到您可以使用 df.columns 获取 dataframedf 的所有 columns 的列表

drop_list = ['a column', 'another column', ...]

df.select([column for column in df.columns if column not in drop_list])

谢谢,这对我删除与另一列同名的重复列很有用,我使用 df.select([df.columns[column_num] for column_num in range(len(df.columns)) if column_num!=2]),我要删除的列的索引为 2。
A
Aron Asztalos

您可以使用两种方式:

1:您只需保留必要的列:

drop_column_list = ["drop_column"]
df = df.select([column for column in df.columns if column not in drop_column_list])  

2:这是更优雅的方式。

df = df.drop("col_name")

您应该避免使用 collect() 版本,因为它会将完整的数据集发送给 master,这将需要大量的计算工作!


k
karlson

您可以明确命名要保留的列,如下所示:

keep = [a.id, a.julian_date, a.user_id, b.quan_created_money, b.quan_created_cnt]

或者在更一般的方法中,您将通过列表理解包含除特定列之外的所有列。例如像这样(不包括 b 中的 id 列):

keep = [a[c] for c in a.columns] + [b[c] for c in b.columns if c != 'id']

最后,您对加入结果进行选择:

d = a.join(b, a.id==b.id, 'outer').select(*keep)

我想我得到了答案。 Select 需要获取字符串列表而不是列列表。这样做:keep = [c for c in a.columns] + [c for c in b.columns if c != 'id'] d = a.join(b, a.id==b.id, 'outer').select(*keep)
好吧,这应该与我的回答完全相同,因为我很确定 select 接受字符串或列 (spark.apache.org/docs/latest/api/python/…)。顺便说一句,在您的第 keep = ... 行中,不需要对 a 使用列表推导:a.columns + [c for c in b.columns if c != 'id'] 应该实现完全相同的效果,因为 a.columns 已经是字符串的 list
@deusxmach1na 实际上,基于字符串的列选择不适用于 OP,因为这不能解决 id 列的歧义。在这种情况下,您必须使用 select 中的 Column 实例。
所有的好点。我在 Spark 1.3 中尝试了您的解决方案并遇到了错误,所以我发布的内容实际上对我有用。为了解决 id 歧义,我在加入之前重命名了我的 id 列,然后在加入之后使用保留列表将其删除。 HTH 其他像我一样被卡住的人。
Y
Yuri Brovman

也许有点离题,但这里是使用 Scala 的解决方案。从您的 oldDataFrame 中创建一个 Array 列名称,然后删除您要删除的列 ("colExclude")。然后将 Array[Column] 传递给 select 并解压缩它。

val columnsToKeep: Array[Column] = oldDataFrame.columns.diff(Array("colExclude"))
                                               .map(x => oldDataFrame.col(x))
val newDataFrame: DataFrame = oldDataFrame.select(columnsToKeep: _*)

k
kyramichel

是的,可以通过这样的切片来删除/选择列:

切片 = data.columns[a:b]

data.select(slice).show()

例子:

newDF = spark.createDataFrame([
                           (1, "a", "4", 0), 
                            (2, "b", "10", 3), 
                            (7, "b", "4", 1), 
                            (7, "d", "4", 9)],
                            ("id", "x1", "x2", "y"))


slice = newDF.columns[1:3]
newDF.select(slice).show()

使用 select 方法获取特征列:

features = newDF.columns[:-1]
newDF.select(features).show()

使用 drop 方法获取最后一列:

last_col= newDF.drop(*features)
last_col.show()

N
New Coder

考虑 2 个数据帧:

>>> aDF.show()
+---+----+
| id|datA|
+---+----+
|  1|  a1|
|  2|  a2|
|  3|  a3|
+---+----+

>>> bDF.show()
+---+----+
| id|datB|
+---+----+
|  2|  b2|
|  3|  b3|
|  4|  b4|
+---+----+

要完成您正在寻找的东西,有两种方法:

1、加盟条件不同。而不是说 aDF.id == bDF.id

aDF.join(bDF, aDF.id == bDF.id, "outer")

写这个:

aDF.join(bDF, "id", "outer").show()
+---+----+----+
| id|datA|datB|
+---+----+----+
|  1|  a1|null|
|  3|  a3|  b3|
|  2|  a2|  b2|
|  4|null|  b4|
+---+----+----+

这将自动摆脱额外的丢弃过程。

2.使用别名:您将丢失与B特定ID相关的数据。

>>> from pyspark.sql.functions import col
>>> aDF.alias("a").join(bDF.alias("b"), aDF.id == bDF.id, "outer").drop(col("b.id")).show()

+----+----+----+
|  id|datA|datB|
+----+----+----+
|   1|  a1|null|
|   3|  a3|  b3|
|   2|  a2|  b2|
|null|null|  b4|
+----+----+----+

t
techgeek

您可以像这样删除列:

df.drop("column Name).columns

在你的情况下:

df.drop("id").columns

如果你想删除多于一列,你可以这样做:

dfWithLongColName.drop("ORIGIN_COUNTRY_NAME", "DEST_COUNTRY_NAME")

Spark 2.4(和最低版本)不接受多个列名。
是否可以按索引删除列?
@seufagner 它只是将其作为列表传递