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
Scala 对从JSON创建的数据帧应用筛选条件_Scala_Apache Spark_Apache Spark Sql - Fatal编程技术网

Scala 对从JSON创建的数据帧应用筛选条件

Scala 对从JSON创建的数据帧应用筛选条件,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我正在处理JSON创建的数据帧,然后我想在数据帧上应用过滤条件 val jsonStr = """{ "metadata": [{ "key": 84896, "value": 54 },{ "key": 1234, "value": 12 }]}""" val rdd = sc.parallelize(Seq(jsonStr)) val df = sqlContext.read.json(rdd) df模式 根 |-元数据:数组nullable=true ||-元素:struct conta

我正在处理JSON创建的数据帧,然后我想在数据帧上应用过滤条件

val jsonStr = """{ "metadata": [{ "key": 84896, "value": 54 },{ "key": 1234, "value": 12 }]}"""
val rdd = sc.parallelize(Seq(jsonStr))
val df = sqlContext.read.json(rdd)
df模式

根 |-元数据:数组nullable=true ||-元素:struct containsnall=true || |-key:long nullable=true || |-value:long nullable=true 现在我需要过滤数据帧,我正试图这样做

val df1=df.where("key == 84896")
这会引发错误

错误执行器-阶段1.0 TID 1中任务0.0中的异常 org.apache.spark.sql.AnalysisException:无法解析给定输入列[metadata]的“`key`”;第1行位置0; “过滤器”键=84896 之所以要使用where子句,是因为要直接使用表达式字符串 例如key==999,value==55 | | key==1234,value==12

首先,您应该使用explode来获得一个易于使用的数据帧。然后,您可以选择给定输入的键和值:

val explodedDF = df.withColumn("metadata", explode($"metadata"))
  .select("metadata.key", "metadata.value")
输出:

+-----+-----+
|  key|value|
+-----+-----+
|84896|   54|
| 1234|   12|
+-----+-----+
这样,您就可以像往常一样执行过滤逻辑:

scala> explodedDF.where("key == 84896").show
+-----+-----+
|  key|value|
+-----+-----+
|84896|   54|
+-----+-----+
您可以连接您的筛选要求,以下是一些示例:

explodedDF.where("key == 84896 AND value == 54")
explodedDF.where("(key == 84896 AND value == 54) OR key = 1234")
从您的问题和评论中我了解到,您试图应用key==999、value==55 | | key==1234、value==12表达式来过滤数据帧行

首先,表达式需要更改,因为它不能作为表达式应用于spark中的dataframe,所以您需要更改为

val expression = """( (key == 999, value == 55) || (key == 1234, value == 12) )"""
val actualExpression = expression.replace(",", " and").replace("||", "or")
这将为您提供新的有效表达式

既然您有了有效的表达式,您的数据帧也需要修改,因为您不能在以数组和结构为模式的列上查询这样的表达式

因此,您需要explode函数将数组元素分解为不同的行,然后使用.*符号选择不同列上struct的所有元素

val df1 = df.withColumn("metadata", explode($"metadata"))
  .select($"metadata.*")
这将为您提供dataframe作为

最后在生成的数据帧上使用有效的表达式

df1.where(s"${actualExpression}")

我希望答案是有帮助的

你是说你想把上面的数组列转换成key==999,value==55 | | key==1234,value==12像字符串一样?@RameshMaharjan不,我想做的基本上是df1=df。其中key==999,value==55 | | key==1234,value==12我已经回答了下面,请看一下:
+-----+-----+
|key  |value|
+-----+-----+
|84896|54   |
|1234 |12   |
+-----+-----+
df1.where(s"${actualExpression}")