pysparkデータフレームの列を削除する方法


83
>>> 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]

2つid: bigintあり、1つ削除したい。どのようにできるのか?

回答:


123

Sparkのドキュメントを読んで、もっと簡単な解決策を見つけました。

drop(col)Sparkのバージョン1.4以降、データフレームのpysparkで使用できる関数があります。

あなたはそれを2つの方法で使うことができます

  1. df.drop('age').collect()
  2. df.drop(df.age).collect()

Pysparkドキュメント-ドロップ


26
データサイズが大きい場合、collect()によってヒープスペースエラーが発生する可能性があります。あなたはまたにより、余分なフィールドをドロップする新しいデータフレームを作成することができますndf = df.drop('age')
mnis.p

1
これは本当に最初の答えになるはずです
vishalv20 5019

97

@Patrickの回答に加えて、以下を使用して複数の列を削除できます

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

4
ドロップ結果をデータフレームに再割り当てする必要がありました:df = df.drop(* columns_to_drop)
avgbody 2018

1
列が存在しない場合はエラーが発生しないことに注意してください
Guido

私はというエラーを取得TreeNodeException: Binding attribute, tree: _gen_alias_34#34私は、列、および使用をドロップした後.show()
frlzjosh

28

これを行うための簡単な方法は、ユーザーには「select」とあなたはすべてのリストを取得することができます実現columnsのためにdataframedfと、df.columns

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

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

1
ありがとう-あなたは、これは私が使用して別の列と同じ名前の重複した列を除去するために私のために素晴らしい作品df.select([df.columns[column_num] for column_num in range(len(df.columns)) if column_num!=2])の列は、私は削除する、インデックス2持っている
シェーンハロラン

12

次のように、保持する列に明示的に名前を付けることができます。

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

または、より一般的なアプローチでは、リスト内包表記を介して特定の列を除くすべての列を含めます。たとえば、次のようになります(idからの列を除くb):

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)
deusxmach1na

select文字列または列のいずれかを受け入れると確信しているので、それは私の答えとまったく同じことをするはずです(spark.apache.org/docs/latest/api/python/…)。ところで、あなたの行keep = ...では、リスト内包表記を使用する必要はありませんa:すでに文字列のa.columns + [c for c in b.columns if c != 'id']場合とまったく同じことを達成する必要a.columnslistあります。
karlson 2015

@ deusxmach1na実際には、文字列に基づく列の選択は、id列のあいまいさを解決しないため、OPでは機能しません。その場合、のColumnインスタンスを使用する必要がありますselect
karlson 2015

すべての良い点。Spark 1.3でソリューションを試したところ、エラーが発生したので、投稿した内容が実際に機能しました。また、IDのあいまいさを解決するために、結合前にid列の名前を変更し、結合後にキープリストを使用して削除しました。私のように立ち往生している他の誰か。
deusxmach1na 2015

12

次の2つの方法を使用できます。

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()バージョンは、完全なデータセットをマスターに送信するため、多大な計算作業が必要になるため、避ける必要があります。


3

トピックから少し外れているかもしれませんが、Scalaを使用したソリューションは次のとおりです。作るArrayあなたから列名のをoldDataFrame、あなたがドロップしたいという列を削除します("colExclude")。次に、Array[Column]を渡してselect解凍します。

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

-1

2つのdataFrameを検討してください。

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

そして

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

あなたが探していることを達成するために、2つの方法があります:

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|
+----+----+----+

-2

次のように列を削除できます。

df.drop("column Name).columns

あなたの場合:

df.drop("id").columns

複数の列を削除する場合は、次の操作を実行できます。

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

1
Spark 2.4(および少なくともバージョン)は、複数の列名を受け入れません。
seufagner

インデックスで列を削除することは可能ですか?
Horbaje

@seufagnerそれはリストとしてそれを渡すだけです
Dee
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.