DataFrame regexp_extract значения из строки, как массив - PullRequest
1 голос
/ 06 марта 2020

Мой DataFrame выглядит следующим образом:

StudentID          Marks
100                ["20", "25.5", "40.23", "50"]
200                ["30", "20", "25", "40"]
300                ["20", "25", "50", "35"]

Мне нужно извлечь marks в массиве и создать новый DataFrame. Тем не менее, я не могу извлечь за второе значение в DF (не знаю, как выбрать все метки с помощью регулярного выражения ([0-9]+)(?:\.[0-9]+){3}.

df1.select(regexp_extract('StudentID', '(\w+)(,)', 1).alias("C1"), 
             regexp_extract('Marks', '([0-9]+)(?:\.[0-9]+){3}', 0).alias("C2"))

В конечном счете, необходимо создать новый DataFrame с форматом ниже :

StudentID  C1    C2    C3     C4
100        20    25.5  40.23  50
200        30    20    25     40
300        20    25    50     35

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 06 марта 2020

Вы можете разбить строку, а затем использовать element_at для извлечения подстрок в отдельные столбцы:

df1.withColumn("marks_array", split( regexp_replace(col("Marks"), "\\[|\\]|\"", ""), ",")  )
      .withColumn("C1", element_at(col("marks_array"), 1))
      .withColumn("C2", element_at(col("marks_array"), 2))
      .withColumn("C3", element_at(col("marks_array"), 3))
      .withColumn("C4", element_at(col("marks_array"), 4))
      .drop("marks_array", "Marks")
      .show(false)
+---------+---+-----+------+---+
|StudentID|C1 |C2   |C3    |C4 |
+---------+---+-----+------+---+
|100      |20 | 25.5| 40.23| 50|
|200      |30 | 20  | 25   | 40|
|300      |20 | 25  | 50   | 35|
+---------+---+-----+------+---+
0 голосов
/ 06 марта 2020

Вы можете использовать from_json для преобразования строкового столбца Marks в массив строк. Затем получите элементы массива для создания каждого столбца.

Однако, если вы не знаете размер массивов, вы можете использовать функцию transform, чтобы преобразовать ее в карту затем взорвите карту и развернитесь, чтобы получить желаемый результат.

transform_expr = """transform(from_json(Marks, 'array<string>'), 
                              (x, i) -> struct(concat('C', i+1), x)
                             )
                 """

df.select(col("*"), explode(map_from_entries(expr(transform_expr)))) \
  .groupBy("StudentID").pivot("key").agg(first("value")) \
  .show()

#+---------+---+----+-----+---+
#|StudentID|C1 |C2  |C3   |C4 |
#+---------+---+----+-----+---+
#|100      |20 |25.5|40.23|50 |
#|200      |30 |20  |25   |40 |
#|300      |20 |25  |50   |35 |
#+---------+---+----+-----+---+

Примечание: функции transfrom и map_from_entries доступны только для Spark 2.4 +

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...