问题陈述:
我有一个包含四列的数据框:service (String)、show (String)、country_1 (Integer) 和 country_2 (Integer)。我的目标是生成一个仅包含两列的数据框:服务(字符串)和信息(地图 [整数,列表 [字符串]])
其中映射可以包含多个键值对记录,例如每个流服务:
{
"34521": ["The Crown", "Bridgerton", "The Queen's Gambit"],
"49678": ["The Crown", "Bridgerton", "The Queen's Gambit"]
}
需要注意的重要一点是,将来可以添加更多国家/地区,例如输入数据框中的另外几列,例如“country_3”、“country_4”等。解决方案代码的目标也是希望能够解决这些问题而不仅仅是像我在下面尝试的解决方案中所做的那样对选定的列进行硬编码,如果这有意义的话。
输入数据框:
架构:
root
|-- service: string (nullable = true)
|-- show: string (nullable = true)
|-- country_1: integer (nullable = true)
|-- country_2: integer (nullable = true)
数据框:
service | show | country_1 | country_2
Netflix The Crown 34521 49678
Netflix Bridgerton 34521 49678
Netflix The Queen's Gambit 34521 49678
Peacock The Office 34521 49678
Disney+ WandaVision 34521 49678
Disney+ Marvel's 616 34521 49678
Disney+ The Mandalorian 34521 49678
Apple TV Ted Lasso 34521 49678
Apple TV The Morning Show 34521 49678
输出数据框:
架构:
root
|-- service: string (nullable = true)
|-- information: map (nullable = false)
| |-- key: integer
| |-- value: array (valueContainsNull = true)
| | |-- element: string (containsNull = true)
数据框:
service | information
Netflix [34521 -> [The Crown, Bridgerton, The Queen’s Gambit], 49678 -> [The Crown, Bridgerton, The Queen’s Gambit]]
Peacock [34521 -> [The Office], 49678 -> [The Office]]
Disney+ [34521 -> [WandaVision, Marvel’s 616, The Mandalorian], 49678 -> [WandaVision, Marvel’s 616, The Mandalorian]]
Apple TV [34521 -> [Ted Lasso, The Morning Show], 49678 -> [Ted Lasso, The Morning Show]]
我已经尝试过的
虽然我已经成功地生成了我想要的输出并粘贴了代码片段,但我不想依赖使用非常基本的 SQL 类型的命令,因为我认为它对于大型数据集的快速计算并不总是最佳的,此外,我不想依赖我在映射时手动选择确切名称的国家列的方法,因为在以后可以添加更多国家列的意义上,这总是会发生变化。
有没有更好的方法来利用 udfs、foldLeft 等类型的代码或其他任何有助于优化的方法,也有助于代码更简洁而不是混乱?
val df = spark.read.parquet("filepath/*.parquet")
val temp = df.groupBy("service", "country_1", "country_2").agg(collect_list("show").alias("show"))
val service_information = grouped.withColumn("information", map(lit($"country_1"), $"show", lit($"country_2"), $"show")).drop("country_1", "country_2", "show")