Я пытаюсь преобразовать необработанные данные «События», поступающие из учетной записи Google Analytics, с помощью PySpark. Каждая запись «Event» имеет поле с именем «event_params», которое содержит подполя в виде пар ключ-значение. Вот пример записи:
| event_date | event_timestamp | event_name | event_params
| -------- | -------- | -------- | ----------------------|
| 20230207 | 1675797300185610| Page View | [{key=engaged_session_event, value = {string_value=null,
int_value=1, float_value=null, double_value=null}},
{key=ga_session_number, value = {string_value=null,
int_value=1, float_value=null, double_value=null}},
{key=page_title, value = {string_value=BlahBlah,
double_value=null}}] |
Я бы хотел, чтобы окончательный набор данных выглядел примерно так:
Я пытался преобразовать поле «event_params» в ArrayType, StructType и строку JSON, но не могу даже извлечь отдельные «ключевые» поля. Как только я смогу это сделать, мне нужно будет игнорировать нулевые «значения» и повернуть оставшиеся пары ключ-значение как новые поля.
Да, каждое поле является строкой: root |-- event_date: строка (nullable = true) |-- event_timestamp: string (nullable = true) |-- event_name: string (nullable = true) |-- event_params: string (nullable = true) |-- event_params: string (nullable = true) = true) |-- event_previous_timestamp: string (nullable = true) |-- event_value_in_usd: string (nullable = true) |-- event_bundle_sequence_id: string (nullable = true) |-- event_server_timestamp_offset: string (nullable = true) |-- user_id: строка (nullable = true)
Одна проблема заключается в том, что строка имеет значения без кавычек, можете ли вы проверить, можете ли вы сохранить ее с кавычками, а затем мы можем взять ее оттуда?
@RonakJain В настоящее время я не могу хранить значения в кавычках.
Вы можете преобразовать строку в допустимую строку json благодаря замене регулярного выражения. Или используйте UDF для его анализа и создания вложенного типа данных.



Попробуй это:
Импорт необходимых пакетов
from pyspark.sql.functions import col, regexp_replace, split, regexp_extract, from_json, struct, coalesce, max
df = df \
.withColumn("event_params", regexp_replace("event_params", "\[", "")) \
.withColumn("event_params", regexp_replace("event_params", "\]", "")) \
.withColumn("event_params", regexp_replace("event_params", "\}},", "}}|")) \
.withColumn("event_params", split("event_params", "\|")) \
.withColumn("event_params", explode("event_params"))
df = df \
.withColumn("event_params", regexp_replace("event_params", " ", "")) \
.withColumn("event_params", regexp_replace("event_params", " = ", ":")) \
.withColumn("event_params", regexp_replace("event_params", ",", "',")) \
.withColumn("event_params", regexp_replace("event_params", "\{", "{'")) \
.withColumn("event_params", regexp_replace("event_params", "\}}", "'}}")) \
.withColumn("event_params", regexp_replace("event_params", ",", ",'")) \
.withColumn("event_params", regexp_replace("event_params", ":", "':'")) \
.withColumn("event_params", regexp_replace("event_params", ":'\{", ":{")) \
.withColumn("event_params", regexp_replace("event_params", "'null'", "null"))
event_paramsdf = df \
.withColumn("event_params", from_json("event_params", MapType(StringType(), StringType()))) \
.withColumn("event_params_key", col("event_params").getField("key")) \
.withColumn("event_params_value", col("event_params").getField("value")) \
.withColumn("event_params_value", from_json("event_params_value", MapType(StringType(), StringType()))) \
df = df.withColumn("event_params_value", coalesce(
"event_params_value.string_value",
"event_params_value.int_value",
"event_params_value.float_value",
"event_params_value.double_value",
))
df = df.groupBy(["event_date", "event_timestamp", "event_name"]).pivot("event_params_key").agg(
max("event_params_value")
)
df.show(truncate=False)
Выход:
+----------+----------------+----------+---------------------+-----------------+----------+
|event_date|event_timestamp |event_name|engaged_session_event|ga_session_number|page_title|
+----------+----------------+----------+---------------------+-----------------+----------+
|20230207 |1675797300185610|Page View |1 |1 |BlahBlah |
+----------+----------------+----------+---------------------+-----------------+----------+
Примечание: я не очень хорошо пишу regexp. Если кто-то может это сделать, не стесняйтесь переформатировать код (2).
@aknickel Не могли бы вы принять это как ответ.
Можете ли вы распечатать и показать схему исходного df, используя
.printSchema()?