Значения столбцов Pyspark автоматически сдвигаются при создании DataFrame - PullRequest
0 голосов
/ 23 апреля 2020

Я пытаюсь создать фрейм данных pyspark вручную, используя следующую вложенную схему -

schema = StructType([
    StructField('fields', ArrayType(StructType([
        StructField('source', StringType()), 
        StructField('sourceids', ArrayType(IntegerType()))]))), 
  StructField('first_name',StringType()), 
  StructField('last_name',StringType()), 
  StructField('kare_id',StringType()),
  StructField('match_key',ArrayType(StringType()))
])

Я использую приведенный ниже код для создания фрейма данных с использованием этой схемы -

row = [Row(fields=[Row(
                    source='BCONNECTED', 
                    sourceids=[10,202,30]), 
                Row(
                    source='KP', 
                    sourceids=[20,30,40])],first_name='Christopher', last_name='Nolan', kare_id='kare1', match_key=['abc','abcd']), 
        Row(fields=[
                Row(
                    source='BCONNECTED', 
                    sourceids=[20,304,5,6]), 
                Row(
                    source='KP',  
                    sourceids=[40,50,60])],first_name='Michael', last_name='Caine', kare_id='kare2', match_key=['ncnc','cncnc'])]

content = spark.createDataFrame(sc.parallelize(row), schema=schema)
content.printSchema()

Схема печатается правильно, но когда я выполняю content.show (), я вижу, что значения столбца kare_id и last_name поменялись местами.

+--------------------+-----------+---------+-------+-------------+
|              fields| first_name|last_name|kare_id|    match_key|
+--------------------+-----------+---------+-------+-------------+
|[[BCONNECTED, [10...|Christopher|    kare1|  Nolan|  [abc, abcd]|
|[[BCONNECTED, [20...|    Michael|    kare2|  Caine|[ncnc, cncnc]|
+--------------------+-----------+---------+-------+-------------+

Ответы [ 2 ]

0 голосов
/ 23 апреля 2020

PySpark сортирует объект Row по именам столбцов, используя лексикографический порядок c. Таким образом, порядок столбцов в ваших данных будет fields, first_name, kare_id, last_name, match_key.

Затем Spark связывает каждое из имен столбцов с данными, что приводит к несоответствию. Исправление заключается в замене записи схемы на last_name и kare_id, как показано ниже:

schema = StructType([
    StructField('fields', ArrayType(StructType([
    StructField('source', StringType()),
    StructField('sourceids', ArrayType(IntegerType()))]))),
    StructField('first_name', StringType()),
    StructField('kare_id', StringType()),
    StructField('last_name', StringType()),
    StructField('match_key', ArrayType(StringType()))
])

Из документов PySpark на строку: «Строка может использоваться для создания объекта строки с использованием именованных аргументов, поля будут отсортированы по именам. "

https://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark. sql .Row

0 голосов
/ 23 апреля 2020

Во-первых, вы фактически определяете схему дважды, когда вы создаете данные, тогда вы уже используете объект строки в СДР, поэтому вам не нужно использовать функцию createDataFrame, вместо этого вы можете выполнить следующее:

sc.parallelize(row).toDF().show()

Но если вы все же хотите упомянуть схему в явном виде, тогда вам нужно держать схему и данные в том же порядке, и ваша упомянутая схема неверна в соответствии с данными, которые вы передаете. Правильная схема будет такой:

schema = StructType([
  StructField('fields', ArrayType(StructType([StructField('source', StringType()),StructField('sourceids', ArrayType(IntegerType()))]))), 
  StructField('first_name',StringType()), 
  StructField('kare_id',StringType()),
  StructField('last_name',StringType()), 
  StructField('match_key',ArrayType(StringType()))
])

kare_id должен предшествовать last_name, потому что это порядок, в котором вы передаете данные

...