PySpark - доступ к имени и значению структурного поля при взрыве - PullRequest
0 голосов
/ 21 мая 2019

Мои входные данные имеют следующую форму:

[
  {
    "id": 123,
    "embedded": {
      "a": {
        "x": true,
        "y": 1,
      },
      "b": {
        "x": false,
        "y": 2,
      },
    }, 
  },
  {
    "id": 456,
    "embedded": {
      "a": {
        "x": false,
        "y": 3,
      },
      "b": {
        "x": true,
        "y": 4,
      },
    }, 
  },
]

Из-за некоторых сложностей моей настройки pyspark поле embedded представляет собой struct с полями a и b на это.Хотя в будущем может появиться больше чем a и b ключей, и я не хочу жестко кодировать список полей в сценарии.

Я бы хотел, чтобы окончательные данные былив форме:

_______________________________
| id   |  key   |   x   |   y  |
_______________________________
| 123  |  a     |  true |   1  |
_______________________________
| 123  |  b     | false |   2  |
_______________________________
| 456  |  a     | false |   3  |
_______________________________
| 456  |  b     |  true |   4  |
_______________________________

Я получаю, что хочу взорвать поле embedded, чтобы получить его различные значения, но как я могу получить доступ к именам полей?

ИспользованиеPySpark ниже, я могу извлечь все значения для столбцов id, x и y, но как я могу получить доступ к именам структурных полей (a, b, ...) при взрыве?

frame = frame.select(
        explode(array("embedded.*")).alias("embedded"),
        frame.id,
    )
    frame = frame.select(
        frame.id,
        frame.embedded.x,
        frame.embedded.y,
    )

1 Ответ

1 голос
/ 21 мая 2019

Если возможно, вы должны использовать MapType вместо

df = spark_session.createDataFrame([
    Row(id=123, embedded={'a': Row(x=True, y=1), 'b': Row(x=False, y=2)}),
    Row(id=456, embedded={'a': Row(x=False, y=3), 'b': Row(x=True, y=4)})
])
df.select(col("id"), explode(col("embedded"))).select(col("id"), col("key"), col("value.*")).show()

Вывод:

.+---+---+-----+---+
| id|key|    x|  y|
+---+---+-----+---+
|123|  a| true|  1|
|123|  b|false|  2|
|456|  a|false|  3|
|456|  b| true|  4|
+---+---+-----+---+

StructType s привязаны к схемам, которые предназначеныбыть статичным.Если вы действительно хотите сделать это за StructType с, запросы должны быть сгенерированы программно

df = spark_session.createDataFrame([
    Row(id=123, embedded=Row(a=Row(x=True, y=1), b=Row(x=False, y=2))),
    Row(id=456, embedded=Row(a=Row(x=False, y=3), b=Row(x=True, y=4)))
])

field_names = [field.name for field in next(field for field in df.schema.fields if field.name=="embedded").dataType.fields]

dfs = [df.select(col("id"), lit(field_name).alias("key"), col(f"embedded.{field_name}.x"), col(f"embedded.{field_name}.y")) for field_name in field_names]

reduce(lambda x,y: x.union(y), dfs).show()

Вывод:

+---+---+-----+---+
| id|key|    x|  y|
+---+---+-----+---+
|123|  a| true|  1|
|456|  a|false|  3|
|123|  b|false|  2|
|456|  b| true|  4|
+---+---+-----+---+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...