Як видалити стовпці у фреймі даних pyspark


82
>>> 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і я хочу видалити одного. Як я можу зробити?

Відповіді:


122

Читаючи документацію до Spark, я знайшов більш просте рішення.

З версії 1.4 іскри існує функція, drop(col)яка може бути використана в pyspark на фреймі даних.

Ви можете використовувати його двома способами

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

Документація Pyspark - Drop


26
коли розмір даних великий, collect () може спричинити помилку простору купи. Ви також можете створити новий фрейм даних, скинувши додаткове поле доndf = df.drop('age')
mnis.p

1
Це справді мала б бути перша відповідь
vishalv2050

97

Додаючи відповідь @ Patrick, ви можете використовувати наступне, щоб скинути кілька стовпців

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

4
Мені довелося перепризначити результати падіння назад до фрейму даних: df = df.drop (* columns_to_drop)
avgbody

1
Зверніть увагу, що ви не отримаєте помилки, якщо стовпець не існує
Гвідо

TreeNodeException: Binding attribute, tree: _gen_alias_34#34.show()
Повідомлення

28

Самий простий спосіб зробити це, щоб користувач « select» і зрозуміти , що ви можете отримати список всіх columnsдля dataframe, dfз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)

Думаю, я отримав відповідь. Виберіть потрібно взяти список рядків, НЕ список стовпців. Отже, зробіть так: 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.columnsвже є listрядком.
karlson

@ deusxmach1na Насправді виділення стовпців на основі рядків не може працювати для OP, оскільки це не вирішить двозначності idстовпця. У цьому випадку вам доведеться використовувати Columnекземпляри в select.
Карлсон,

Усі хороші бали. Я спробував ваше рішення в Spark 1.3 і отримав помилки, тому те, що я розмістив, насправді працювало для мене. І для вирішення двозначності ідентифікатора я перейменував свій стовпець ідентифікатора перед приєднанням, а потім скинув його після приєднання за допомогою списку збереження. HTH будь-хто інший, хто застряг, як і я.
deusxmach1na

12

Ви можете використовувати два способи:

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 фрейми даних:

>>> 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 у цьому.

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

Чи можна скидати стовпці за індексом?
Горбає

@seufagner просто передає його як список
Dee
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.