Apache spark Spark数据帧中从数组中提取单个元素
我有一个具有以下结构的Apache spark Spark数据帧中从数组中提取单个元素,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,我有一个具有以下结构的数据集: {"name": "Ben", "lastHolidayDestination": "Florida", "holidays": [ {"destination": "Florida", "year": 2020}, {"destination": "
数据集
:
{"name": "Ben",
"lastHolidayDestination": "Florida",
"holidays": [
{"destination": "Florida",
"year": 2020},
{"destination": "Lille",
"year": 2019}
]}
我想使用Spark SQL向数据集的根添加一个新列lastHolidayYear
,通过查找连接到lastHolidayDestination
的holidays
元素填充该列(假设只有一个)。因此,输出数据集将是:
{"name": "Ben",
"lastHolidayDestination": "Florida",
"lastHolidayYear": 2020,
"holidays": [
{"destination": "Florida",
"year": 2020},
{"destination": "Lille",
"year": 2019}
]}
我一直在玩
dataset.withColumn()
和when()
(使用Java,但Scala/Python的答案很好),但到目前为止我什么都没有。我真的不想使用UDF,除非我不得不这样做。有什么建议吗?要使用数组模拟连接,可以使用“展平”和“筛选”组合:
val result = ds.withColumn("expl", explode(col("holidays")))
.filter("lastHolidayDestination = expl.destination")
.withColumn("lastHolidayYear", col("expl.year"))
.drop("expl")
自Spark 3.0以来,您可以先过滤数组,然后使用以下表达式获取数组的第一个元素:
import org.apache.spark.sql.functions.{element_at,filter,col}
val extractElementExpr=元素(过滤器(col(“myArrayColumnName”),myCondition),1)
其中,“myArrayColumnName”
是包含数组的列的名称,myCondition
是条件,它是一个列=>列
表达式
对于您的特定示例,代码为:
import org.apache.spark.sql.functions.{col,element_at,filter}
导入org.apache.spark.sql.Column
val islastoliday=(c:Column)=>c.getField(“目的地”)==col(“lastHolidayDestination”)
val getLastHoliday=元素(过滤器(列(“假日”),isLastHoliday),1)
val result=df.withColumn(“lastHolidayYear”,getLastHoliday.getField(“year”))
使用此代码,如果输入数据帧包含以下值:
+------+----------------------+--------------------------------+
|name |lastHolidayDestination|holidays |
+------+----------------------+--------------------------------+
|Ben |Florida |[[Florida, 2020], [Lille, 2019]]|
|Alice |Peru |[[Florida, 2020], [Lille, 2019]]|
|Robert|Lille |[[Florida, 2020], [Lille, 2019]]|
+------+----------------------+--------------------------------+
输出将是:
+------+----------------------+--------------------------------+---------------+
|name |lastHolidayDestination|holidays |lastHolidayYear|
+------+----------------------+--------------------------------+---------------+
|Ben |Florida |[[Florida, 2020], [Lille, 2019]]|2020 |
|Alice |Peru |[[Florida, 2020], [Lille, 2019]]|null |
|Robert|Lille |[[Florida, 2020], [Lille, 2019]]|2019 |
+------+----------------------+--------------------------------+---------------+
您可以使用SQL查询数组和对象。。。这些不是“嵌套数据帧”。例如,选择“感谢”中的“年度最大值”列,我来看看。为了清楚起见,我特别希望根据一个值来选择元素,而不是一个max/min。我的实际用例更复杂(你是对的,在这个简化的示例中,它不是嵌套的,所以我将对它进行重命名),但我只是把它简化为一些更简单的东西。对我来说,看起来你想要设置
lastHolidayYear=max(year)在节假日
。。。这不对吗?“通过查找连接到lastHolidayDestination的holidays元素填充”所以不,不是maxAh。我通过“last”假设您正在数组中查找具有最大年份的元素。在这种情况下,您不需要单独存储Florida,因为这将是来自原始数据集的派生视图