dataframe - 基于子列转置火花数据帧
问题描述
我有一个看起来像这样的火花数据框:
root
|-- 0000154d-7585-5eb283ff985c: struct (nullable = true)
| |-- collaborative_rank: array (nullable = true)
| | |-- element: long (containsNull = true)
| |-- content_rank: array (nullable = true)
| | |-- element: long (containsNull = true)
| |-- curated_rank: array (nullable = true)
| | |-- element: long (containsNull = true)
| |-- discovery_score: array (nullable = true)
| | |-- element: long (containsNull = true)
| |-- original_rank: array (nullable = true)
| | |-- element: long (containsNull = true)
| |-- recipe_id: array (nullable = true)
| | |-- element: long (containsNull = true)
|-- 00005426-2675-68085cd359c7: struct (nullable = true)
| |-- collaborative_rank: array (nullable = true)
| | |-- element: long (containsNull = true)
| |-- content_rank: array (nullable = true)
| | |-- element: long (containsNull = true)
| |-- curated_rank: array (nullable = true)
| | |-- element: long (containsNull = true)
| |-- discovery_score: array (nullable = true)
| | |-- element: long (containsNull = true)
| |-- original_rank: array (nullable = true)
| | |-- element: long (containsNull = true)
| |-- recipe_id: array (nullable = true)
| | |-- element: long (containsNull = true)
每列是一个用户 ID,例如0000154d-7585-5eb283ff985c
,每行由 15 000 个用户组成(它们来自每个包含 15 000 个用户的 json 文件)。
我想转置它,使每个用户 id 是一行,每个子列collaborative_rank, content_rank, curated_rank, discovery_score, original_rank and recipe_id
是一列,数组是值。我是火花新手,有什么无痛的方法可以做到这一点吗?
编辑:
作为参考,我正在读取的输入 .json 文件如下所示:
{"0000154d-7585-4096-a71a-5eb283ff985c": {"recipe_id": [1, 2, 3], "collaborative_rank": [1, 2, 3], "curated_rank": [1, 2, 3], "discovery_score": [1]}, "00005426-2675-4940-8394-e8085cd359c7": {"recipe_id": [] ... }
等等
解决方案
如果不想将其转换为 rdd 并执行 UDF,可以考虑堆叠数据框。
df = spark.read.json(r'C:\stackoverflow\samples\inp.json')
stack_characteristics = str(len(df.columns))+','+','.join([f"'{v}',`{v}`" for v in df.columns])
df.select(expr(f'''stack({stack_characteristics})''').alias('userId','vals')).\
select('userId', 'vals.*').show()
+--------------------+------------------+------------+---------------+---------+
| userId|collaborative_rank|curated_rank|discovery_score|recipe_id|
+--------------------+------------------+------------+---------------+---------+
|0000154d-7585-409...| [1, 2, 3]| [1, 2, 3]| [1]|[1, 2, 3]|
|00005426-2675-494...| [1, 2, 3]| [1, 2, 3]| [1]|[1, 2, 3]|
+--------------------+------------------+------------+---------------+---------+
推荐阅读
- spark-ar-studio - Spark AR CAMERA 放大和缩小
- vue.js - 忽略 VueJS 组件文件的代码覆盖率,尽管这些组件的测试已成功运行
- docker-compose - 无法从 dotnet 包中排除 *.dcproj
- python - 在父类本身中使用了“super()”,为什么?
- c# - 正确通过 foreach 循环中的日期列表
- java - 将java的小数点四舍五入而不重新分配给新变量
- reactjs - 使用 filepond 文件上传器和另一个输入字段将表单数据提交到后端
- php - 如何使用 php 将时间字符串 'March, 05 2019 08:37:32 +0000' 转换为 '2019-03-05 08:37:32'
- php - PHP Laravel Dusk 使用美国日期时间格式
- java - JDK 7 和 8 中的 new String(byte []) 结果不同