Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark Spark数据帧中从数组中提取单个元素_Apache Spark_Apache Spark Sql - Fatal编程技术网

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,因为这将是来自原始数据集的派生视图