Как создать копию фрейма данных в pyspark? - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть фрейм данных, из которого мне нужно создать новый фрейм данных с небольшим изменением схемы, выполнив следующую операцию.

>>> X = spark.createDataFrame([[1,2], [3,4]], ['a', 'b'])
>>> schema_new = X.schema.add('id_col', LongType(), False)
>>> _X = X.rdd.zipWithIndex().map(lambda l: list(l[0]) + [l[1]]).toDF(schema_new)

Проблема заключается в том, что в приведенной выше операции схемаX меняется на месте.Поэтому, когда я печатаю X.columns, я получаю

>>> X.columns
['a', 'b', 'id_col']

, но значения в X остаются теми же

>>> X.show()
+---+---+
|  a|  b|
+---+---+
|  1|  2|
|  3|  4|
+---+---+

Чтобы избежать изменения схемы X, я попыталсясоздание копии X с использованием трех способов - с использованием методов copy и deepcopy из модуля copy - просто с помощью _X = X

Сбой методов copy и возвращение

RecursionError: maximum recursion depth exceeded

Метод назначения также не работает

>>> _X = X
>>> id(_X) == id(X)
True

Поскольку их id одинаковы, создание дублированного фрейма данных здесь не очень помогает, и операции, выполняемые на _Xотразить в X.

Так что мой вопрос действительно состоит из двух частей:

  • как изменить схему схемы (то есть без внесения каких-либо изменений в X)?

  • и, что более важно, как создать дубликат фрейма данных pyspark?

Примечание:

Этот вопрос является продолжением этой записи

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Как объяснено в ответе на другой вопрос, вы могли бы сделать детальную копию своей исходной схемы. Затем мы можем изменить эту копию и использовать ее для инициализации нового DataFrame _X:

import pyspark.sql.functions as F
from pyspark.sql.types import LongType
import copy

X = spark.createDataFrame([[1,2], [3,4]], ['a', 'b'])
_schema = copy.deepcopy(X.schema)
_schema.add('id_col', LongType(), False) # modified inplace
_X = X.rdd.zipWithIndex().map(lambda l: list(l[0]) + [l[1]]).toDF(_schema)

Теперь давайте проверим:

print('Schema of X: ' + str(X.schema))
print('Schema of _X: ' + str(_X.schema))

Выход:

Schema of X: StructType(List(StructField(a,LongType,true),StructField(b,LongType,true)))
Schema of _X: StructType(List(StructField(a,LongType,true),
                  StructField(b,LongType,true),StructField(id_col,LongType,false)))

Обратите внимание, что для копирования DataFrame вы можете просто использовать _X = X. Каждый раз, когда вы добавляете новый столбец, например, withColumn, объект не изменен на месте, но возвращается новая копия. Надеюсь, это поможет!

0 голосов
/ 12 сентября 2018

В Scala:

  1. С "X.schema.copy" новый экземпляр схемы создается без изменения старой схемы;
  2. В каждой операции Dataframe, которая возвращает Dataframe ("select", "где" и т. д.), новый Dataframe создается без изменения оригинала.Оригинал можно использовать снова и снова.Угадай, дублирование не требуется для твоего дела.Производительность - это отдельная проблема, можно использовать «persist».
...