apache-spark - 在火花数据框中的每一行的地图类型列中按键排序
问题描述
我有以下格式的火花数据框:
Name LD_Value
A37 Map(10 -> 0.20,5 -> 0.30,17 -> 0.25)
A39 Map(11 -> 0.40,6 -> 0.67,24 -> 0.45)
我需要根据LD_Value
每条记录的列中的键按降序排序。
预期输出:
Name LD_Value
A37 Map(17 -> 0.25,10 -> 0.20,5 -> 0.30)
A39 Map(24 -> 0.45,11 -> 0.40,6 -> 0.67)
是否可以对火花数据框中的地图类型列进行排序?
我研究了 spark 高阶函数,但没有运气。
解决方案
您可以首先使用map_keys
函数获取映射的键,对键数组进行排序,然后使用从原始映射中获取每个键元素的对应值,最后通过使用函数transform
从两个数组创建新映射来更新映射列map_from_arrays
.
对于Spark 3+,您可以使用比较器函数作为 function 的第二个参数,按降序对键数组进行排序array_sort
:
from pyspark.sql import functions as F
df1 = df.withColumn(
"LD_Value_keys",
F.expr("array_sort(map_keys(LD_Value), (x, y) -> case when x > y then -1 when x < y then 1 else 0 end)")
).withColumn("LD_Value_values", F.expr("transform(LD_Value_keys, x -> LD_Value[x])")) \
.withColumn("LD_Value", F.map_from_arrays(F.col("LD_Value_keys"), F.col("LD_Value_values"))) \
.drop("LD_Value_keys", "LD_Value_values")
df1.show()
#+----+----------------------------------+
#|Name|LD_Value |
#+----+----------------------------------+
#|A37 |[17 -> 0.25, 10 -> 0.2, 5 -> 0.3] |
#|A39 |[24 -> 0.45, 11 -> 0.4, 6 -> 0.67]|
#+----+----------------------------------+
对于Spark < 3,您可以使用此 UDF 按降序对数组进行排序:
# array_sort_udf (array, reverse): if reverse = True then desc
array_sort_udf = F.udf(lambda arr, r: sorted(arr, reverse=r), ArrayType(StringType()))
并像这样使用它:
df.withColumn("LD_Value_keys", array_sort_udf(F.map_keys(F.col("LD_Value")), F.lit(True)))
推荐阅读
- python - 在 AWS 上部署 django 时出现 Pytorch 导入错误
- python - Elif 语句似乎没有正确读取变量
- javascript - 在 Shopify 中刷新异步购物车以更新忠诚度积分值
- sql - 在 Snowflake IN 子查询中使用 UPPER 时获取“无法评估不支持的子查询类型”
- visual-studio-code - 我在vscode中使用puppeteer将md文件转换为pdf,但是,转换后我文件中的所有公式都消失了
- django - 未找到带有参数“(”,)”的“后详细信息”的反向。尝试了 1 种模式:['post\\/(?P
[0-9]+)\\/$'] - google-cloud-platform - 如何解决 BigQuery Storage API 429 配额错误
- angular - 发出 HTTP 请求时,RxJS 订阅如何工作?
- javascript - Javascript中的图案设计和地图功能。什么不起作用?
- python - PyPy3 中两个相似的代码速度不同