根据列的值转换spark Dataframe

tyu7yeag  于 2023-02-09  发布在  Apache
关注(0)|答案(1)|浏览(135)

假设我有下面的 Dataframe :
| s.id | s.first|s.last|s.age|d.first|d.last|d.age|更新字段|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 1个|美国汽车协会|血脑屏障|十个|美国汽车协会|血脑屏障|十个|["第一"]|
| 第二章|CCC|限定日|二十个|CCC__|限定日|二十一|["第一"、"年龄"]|
我希望将其转换为以下格式,因此对于第一个 Dataframe 中的每个UPDATED_FIELDS,我希望在第二个 Dataframe 中创建一个新行。
| 身份证|场|s_值|d_值|
| - ------|- ------|- ------|- ------|
| 1个|第一|美国汽车协会|AAA级--|
| 第二章|第一|CCC|CCC--|
| 第二章|年龄|二十个|二十一|
我觉得我需要创建一个新的 Dataframe ,但无法使其工作

bvn4nwqk

bvn4nwqk1#

这并不简单,因为在分解"UPDATED_FIELDS"以创建"field"列之后,您会得到以下 Dataframe :

+----+-------+------+-----+-------+------+-----+--------------+-----+
|s.id|s.first|s.last|s.age|d.first|d.last|d.age|UPDATED_FIELDS|field|
+----+-------+------+-----+-------+------+-----+--------------+-----+
|   1|    AAA|   BBB|   10|  AAA__|   BBB|   10|       [first]|first|
|   2|    CCC|   DDD|   20|  CCC__|   DDD|   21|  [first, age]|first|
|   2|    CCC|   DDD|   20|  CCC__|   DDD|   21|  [first, age]|  age|
+----+-------+------+-----+-------+------+-----+--------------+-----+

新的列s_valued_value依赖于使用分解列"field"中的文字来告诉我们使用哪一列的值。

df.withColumn(
    "field", F.explode("UPDATED_FIELDS")
).withColumn(
    "s_value", F.col(f"s.{F.col('field')}")
)

...但这将导致错误,因为{F.col('field')}不能解释为文本。
更新:基于this helpful answer,实际上可以使用字符串文字作为列查找。您需要首先确保可以访问df['field'],因此需要先单独执行分解,然后使用F.coalesce(*F.when(...))作为从df['field']中的字符串获取列名中的值的方法:

df = df.withColumn(
    "field", F.explode("UPDATED_FIELDS")
)

## obtain list of all unique strings in "field"
base_cols = df.select(F.collect_set("field").alias("column")).first()["column"]

df.withColumn(
    "s_value",  F.coalesce(*[F.when(df['field'] == c, df[f"`s.{c}`"]) for c in base_cols])
).withColumn(
    "d_value",  F.coalesce(*[F.when(df['field'] == c, df[f"`d.{c}`"]) for c in base_cols])
).select(
    F.col("`s.id`").alias("id"),"field","s_value","d_value"
)

+---+-----+-------+-------+
| id|field|s_value|d_value|
+---+-----+-------+-------+
|  1|first|    AAA|  AAA__|
|  2|first|    CCC|  CCC__|
|  2|  age|     20|     21|
+---+-----+-------+-------+

相关问题