使用来自另一列的键从 MapType 列查找值
Lookup values from a MapType column with keys from another column
我有一个包含两列的 Spark 流数据框。一个 Integer id 列和一个 MapType 列,其中 Integer Id 作为键,JSON 对象作为值。
---------------------------------------------------------------------------------------------------------------
id objects
---------------------------------------------------------------------------------------------------------------
1 | (1 -> {"id" : 1, "type": "jpeg"}, 2 -> {"id" : 2, "type": "gif"}, 3 -> {"id" : 3, "type": "png"})
5 | (1 -> {"id" : 1, "type": "jpeg"}, 2 -> {"id" : 2, "type": "gif"}, 3 -> {"id" : 3, "type": "png"})
2 | (1 -> {"id" : 1, "type": "jpeg"}, 2 -> {"id" : 2, "type": "gif"}, 3 -> {"id" : 3, "type": "png"})
---------------------------------------------------------------------------------------------------------------
我想构建一个新的数据框,其中只有一个列包含 JSON 对象,其键与 id 列匹配。
----------------------------------------------------------------------
objects
----------------------------------------------------------------------
{"id" : 1, "type": "jpeg"}
{"id" : 2, "type": "gif" }
----------------------------------------------------------------------
最好的方法是什么?我实现了一个 Scala udf 来执行查找和 returns 相应的对象值,但想知道是否可以使用内置的 Spark 函数来完成相同的操作。
我试过这样做:
df.withColumn("obj", $"objects".getItem($"id"))
但是抛出异常:
java.lang.RuntimeException: Unsupported literal type class org.apache.spark.sql.ColumnName
这是有道理的,因为 $"id"
是列类型。但是,如果我进行收集,那将导致我希望避免的行为。
不需要 UDF,您可以使用内置功能来执行此操作。但是,您不能使用 getItem
,因为参数是另一列,而不是字符串值。
相反,您可以按如下方式从地图中获取值:
df.withColumn("value", $"objects"($"id"))
要创建一个新的数据框并删除 id 在地图中不存在的行,
df.select($"objects"($"id").as("objects")).na.drop
这会给你,
+-------------------------+
|objects |
+-------------------------+
|{"id": 1, "type": "jpeg"}|
|{"id": 3, "type": "png"} |
+-------------------------+
我有一个包含两列的 Spark 流数据框。一个 Integer id 列和一个 MapType 列,其中 Integer Id 作为键,JSON 对象作为值。
---------------------------------------------------------------------------------------------------------------
id objects
---------------------------------------------------------------------------------------------------------------
1 | (1 -> {"id" : 1, "type": "jpeg"}, 2 -> {"id" : 2, "type": "gif"}, 3 -> {"id" : 3, "type": "png"})
5 | (1 -> {"id" : 1, "type": "jpeg"}, 2 -> {"id" : 2, "type": "gif"}, 3 -> {"id" : 3, "type": "png"})
2 | (1 -> {"id" : 1, "type": "jpeg"}, 2 -> {"id" : 2, "type": "gif"}, 3 -> {"id" : 3, "type": "png"})
---------------------------------------------------------------------------------------------------------------
我想构建一个新的数据框,其中只有一个列包含 JSON 对象,其键与 id 列匹配。
----------------------------------------------------------------------
objects
----------------------------------------------------------------------
{"id" : 1, "type": "jpeg"}
{"id" : 2, "type": "gif" }
----------------------------------------------------------------------
最好的方法是什么?我实现了一个 Scala udf 来执行查找和 returns 相应的对象值,但想知道是否可以使用内置的 Spark 函数来完成相同的操作。
我试过这样做:
df.withColumn("obj", $"objects".getItem($"id"))
但是抛出异常:
java.lang.RuntimeException: Unsupported literal type class org.apache.spark.sql.ColumnName
这是有道理的,因为 $"id"
是列类型。但是,如果我进行收集,那将导致我希望避免的行为。
不需要 UDF,您可以使用内置功能来执行此操作。但是,您不能使用 getItem
,因为参数是另一列,而不是字符串值。
相反,您可以按如下方式从地图中获取值:
df.withColumn("value", $"objects"($"id"))
要创建一个新的数据框并删除 id 在地图中不存在的行,
df.select($"objects"($"id").as("objects")).na.drop
这会给你,
+-------------------------+
|objects |
+-------------------------+
|{"id": 1, "type": "jpeg"}|
|{"id": 3, "type": "png"} |
+-------------------------+