Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.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_Dataframe_Rdd - Fatal编程技术网

Scala 根据条件删除数据帧(JSON)中的嵌套数组项

Scala 根据条件删除数据帧(JSON)中的嵌套数组项,scala,apache-spark,dataframe,rdd,Scala,Apache Spark,Dataframe,Rdd,我在一个数据框中读取了一个巨大的文件,其中每行包含一个JSON对象,如下所示: { "userId": "12345", "vars": { "test_group": "group1", "brand": "xband" }, "modules": [ { "id": "New" }, { "id": "Default" }, { "id": "BestValue" },

我在一个数据框中读取了一个巨大的文件,其中每行包含一个JSON对象,如下所示:

{
  "userId": "12345",
  "vars": {
    "test_group": "group1",
    "brand": "xband"
  },
  "modules": [
    {
      "id": "New"
    },
    {
      "id": "Default"
    },
    {
      "id": "BestValue"
    },
    {
      "id": "Rating"
    },
    {
      "id": "DeliveryMin"
    },
    {
      "id": "Distance"
    }
  ]
}

我如何以这种方式操纵数据帧,只保留id=“Default”的模块?如果id不等于“Default”

正如您所说,您在每一行中都给出了
json
格式

{"userId":"12345","vars":{"test_group":"group1","brand":"xband"},"modules":[{"id":"New"},{"id":"Default"},{"id":"BestValue"},{"id":"Rating"},{"id":"DeliveryMin"},{"id":"Distance"}]}
{"userId":"12345","vars":{"test_group":"group1","brand":"xband"},"modules":[{"id":"New"},{"id":"Default"},{"id":"BestValue"},{"id":"Rating"},{"id":"DeliveryMin"},{"id":"Distance"}]}
如果这是真的,那么您可以使用
sqlContext
json
api将
json
文件读取到
dataframe
,如下所示

val df = sqlContext.read.json("path to json file")
这将为您提供
dataframe
as

+--------------------------------------------------------------------+------+--------------+
|modules                                                             |userId|vars          |
+--------------------------------------------------------------------+------+--------------+
|[[New], [Default], [BestValue], [Rating], [DeliveryMin], [Distance]]|12345 |[xband,group1]|
|[[New], [Default], [BestValue], [Rating], [DeliveryMin], [Distance]]|12345 |[xband,group1]|
+--------------------------------------------------------------------+------+--------------+
{"modules":"Default","userId":"12345","vars":{"brand":"xband","test_group":"group1"}}
{"modules":"Default","userId":"12345","vars":{"brand":"xband","test_group":"group1"}}
schema
be

root
 |-- modules: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- id: string (nullable = true)
 |-- userId: string (nullable = true)
 |-- vars: struct (nullable = true)
 |    |-- brand: string (nullable = true)
 |    |-- test_group: string (nullable = true)
最后一步是使用
默认值
仅过滤
模块.id

val finaldf = df.withColumn("modules", explode($"modules.id"))
    .filter($"modules" === "Default")
应该给你什么

+-------+------+--------------+
|modules|userId|vars          |
+-------+------+--------------+
|Default|12345 |[xband,group1]|
|Default|12345 |[xband,group1]|
+-------+------+--------------+
我希望答案是有帮助的

已更新

这将创建
json
作为

+--------------------------------------------------------------------+------+--------------+
|modules                                                             |userId|vars          |
+--------------------------------------------------------------------+------+--------------+
|[[New], [Default], [BestValue], [Rating], [DeliveryMin], [Distance]]|12345 |[xband,group1]|
|[[New], [Default], [BestValue], [Rating], [DeliveryMin], [Distance]]|12345 |[xband,group1]|
+--------------------------------------------------------------------+------+--------------+
{"modules":"Default","userId":"12345","vars":{"brand":"xband","test_group":"group1"}}
{"modules":"Default","userId":"12345","vars":{"brand":"xband","test_group":"group1"}}
但如果你的要求是得到如下

{"modules":{"id":"Default"},"userId":"12345","vars":{"brand":"xband","test_group":"group1"}}
{"modules":{"id":"Default"},"userId":"12345","vars":{"brand":"xband","test_group":"group1"}}
您应该分解
模块
,而不是
模块.id

val finaldf = df.withColumn("modules", explode($"modules"))
    .filter($"modules.id" === "Default")

这接近于解决方案,但不幸的是,如果在此之后编写JSON文件,它将在模块数组中具有“Default”作为简单字符串元素。见:。。。“模块”:“默认值”、。。。我想将它作为{}中的JSON元素保留为“modules”:{“id”:“Default”}我不想丢失结构/schema.Upvote并接受您的答案。您是否也有一个在筛选器()中没有隐式的解决方案?我的意思是不要使用$and==更不用说上面的了。我应该如何传入多个模块上的字符串和筛选器列表?类似于:filter(validModules.contains($“modules.id”))您应该使用udf函数:)请问另一个问题,因为这个答案足以回答这个问题。:)定义一个数组
val validModules=array(“Dfault”,“default”)
定义一个udf函数
def contains=udf((list:mutable.WrappedArray[String],String:String)=>list.contains(String))
并将过滤器中的udf函数用作
过滤器(contains(lit(validModules),$“modules.id”)