apache-spark - 在explode“子查询”中有效地插入when语句
问题描述
我有以下列命名data
,它是具有多列的数据框的一部分:
[{"country": "FR", "createdAt": "Mon, 07 Dec 20 16:35:10 +0000", "id": 1, "stuff": ["a"]}, {"country": "UK", "createdAt": "Mon, 07 Dec 20 16:35:10 +0000", "id": 2, "stuff": ["a", "b"]}, {"country": "DE", "createdAt": "Mon, 07 Dec 20 16:35:10 +0000", "id": 3, "stuff": ["a", "b", "c"]}, {"country": "IT", "createdAt": "Mon, 07 Dec 20 16:35:10 +0000", "id": 4, "stuff": ["b"]}]
我想分解这个名为的列data
,使其具有一个数据框,其中包含每个键值对的列。还有一个带有stuff
键的嵌套数组,我想用条件语句将其展平。
我有以下一组运行正常的命令:
#reading api response
df = spark.read.json(sc.parallelize([json.dumps(response)]))
#first call
df = df.withColumn("data", explode("data")).select(
col("data")["country"].alias('country'),col("data")["createdAt"].alias('creation'), col("data")["stuff"].alias('stuff'))
#second call
df = df.withColumn("stuff", when(array_contains(df.stuff, "a"),"a")
.otherwise("Other"))
display(df)
但是我想知道是否可以在带有该语句的“第一次调用”中插入WithColumn
带有该方法的第二条语句。我觉得不得不三次调用 df 有点多余。array_contains
explode
解决方案
不可能将第二个withColumn
语句放在第一个调用中,因为stuff
column 在数组列内,所以没有办法避免这两个步骤(根据我对 Spark 的了解)。
要减少方法调用,您可以这样做:
df = (df
.selectExpr('inline(data)')
.select("country",
col("createdAt").alias("creation"),
"id",
when(array_contains("stuff", "a"), "a").otherwise("Other").alias("stuff")))
为避免select
再次调用:
df = (df
.selectExpr('inline(data)')
.withColumnRenamed("createdAt", "creation")
.withColumn("stuff", when(array_contains("stuff", "a"), "a").otherwise("Other").alias("stuff")))
在引擎盖下,两个选项都将执行相同的物理计划和执行
推荐阅读
- html - 如何在 css 中设置表单输入的样式?
- html - Flex 1 全宽列然后两列
- azure-data-explorer - 对相似的列字符串值进行分组
- javascript - 如何访问 JavaScript 函数中的当前上下文?
- jsf - 显示来自 String Primefaces 的图像
- java - 将 Java AWS S3 代码部署到 openfaas 时出错
- java - Junit 测试未在 AWS 上运行。只有设置和拆除工作
- cloud-foundry - 在 Cloud Foundry 健康检查中,“[HEALTH / 0] ERR 无法在端口 8080 上向 '/health' 发出 HTTP 请求:在 0 毫秒内收到状态代码 404”
- gatling - Gatling 保存 html 输入
- javascript - 使用 useEffect 时的无限循环