如何将 map_keys() 中的值拆分为 PySpark 中的多列

Posted

技术标签:

【中文标题】如何将 map_keys() 中的值拆分为 PySpark 中的多列【英文标题】:How to split values from map_keys() into multiple columns in PySpark 【发布时间】:2020-04-29 22:04:03 【问题描述】:

我有这个数据框,它的架构带有如下图:

root
 |-- events: map (nullable = true)
 |    |-- key: string
 |    |-- value: string (valueContainsNull = true)

当我分解它或使用 map_keys() 来获取这些值时,我会在下面得到这个数据框:

+--------------------+--------------------+
|            map_data|          map_values|
+--------------------+--------------------+
|[[event_name=walk..|[event_name=walk...|
|[[event_name=walk..|          2019-02-17|
|[[event_name=walk..|            08:00:00|
|[[event_name=run...|[event_name=walk...|
|[[event_name=fly...|          2019-02-17|
|[[event_name=run...|            09:00:00|
+--------------------+--------------------+

这是我访问上面显示的数据框的代码:

events = event_data\
   .withColumn(
      "map_data", 
      F.map_values(event_data.events)
   )
events.printSchema()
events.select("map_data")
   .withColumn(
      "map_values", 
      F.explode(events.map_data)
   ).show(10)

从一开始,我认为这是一个里程碑,但是,我希望我的数据框看起来像这样:

+--------------------+-----------+--------+
|          events    |     date  |   time |
+--------------------+-----------+--------+
|[event_name=walk...| 2019-02-17|08:00:00|
|[event_name=walk...| 2019-02-17|09:00:00|
+--------------------+-----------+--------+

我一直在研究,我看到人们正在使用 udf,但是,我确信有一种方法可以完全使用数据帧和 sql 函数来完成我想要的。

为了更深入地了解这里是我的行在没有 .show(truncate=False) 时的样子

+--------------------+--------------------+
|            map_data|          map_values|
+--------------------+--------------------+
|[[event_name=walk..|[event_name=walk, duration=0.47, x=0.39, y=0.14, timestamp=08:02:30.574892, event_name=walk, duration=0.77, x=0.15, y=0.08, timestamp=08:02:50.330245, event_name=run, duration=0.02, x=0.54, y=0.44, timestamp=08:02:22.737803, event_name=run, duration=0.01, x=0.43, y=0.56, timestamp=08:02:11.629404, event_name=run, duration=0.03, x=0.57, y=0.4, timestamp=08:02:22.660778, event_name=run, duration=0.02, x=0.49, y=0.49, timestamp=08:02:56.660186]|
|[[event_name=walk..|          2019-02-17|
|[[event_name=walk..|            08:00:00|

此外,对于我现在拥有的数据框,我的问题是找出如何将数组分解为多列。我之所以提到这个原因,是因为我可以使用它或执行更有效的过程来根据给定的地图创建数据框。

【问题讨论】:

您能否使用.show(truncate=False) 提供第一个events 列的完整视图 【参考方案1】:

我找到了解决问题的方法。我需要采用这种方法 (Create a dataframe from a hashmap with keys as column names and values as rows in Spark) 并在 event_data 这是我的初始化数据帧上执行这些计算。

这就是我的数据框现在的样子

|25769803776|2019-03-19|[event_name=walk, duration=0.47, x=0.39, y=0.14, timestamp=08:02:30.574892, event_name=walk, duration=0.77, x=0.15, y=0.08, timestamp=08:02:50.330245, event_name=run, duration=0.02, x=0.54, y=0.44, timestamp=08:02:22.737803, event_name=run, duration=0.01, x=0.43, y=0.56, timestamp=08:02:11.629404, event_name=run, duration=0.03, x=0.57, y=0.4, timestamp=08:02:22.660778, event_name=run, duration=0.02, x=0.49, y=0.49, timestamp=08:02:56.660186]|08:02:00|

【讨论】:

以上是关于如何将 map_keys() 中的值拆分为 PySpark 中的多列的主要内容,如果未能解决你的问题,请参考以下文章

如何将值字段拆分为水晶报表中的更多字段?

使用 SSIS 包将一个字段中的值拆分为两个值,以便在 SQL Server 中的两个不同字段中使用

oracle 如何将一个字段里的值拆分为多个值显示出来

如何根据c#中的值拆分数据

Oracle通过一个字段的值将一条记录拆分为多条记录

将逗号分隔值拆分为 Oracle 中的列