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 如何将Spark SQL DataFrame与flatMap一起使用?_Scala_Apache Spark_Apache Spark Sql - Fatal编程技术网

Scala 如何将Spark SQL DataFrame与flatMap一起使用?

Scala 如何将Spark SQL DataFrame与flatMap一起使用?,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我正在使用Spark Scala API。我有一个Spark SQL数据帧(从Avro文件读取),具有以下模式: root |-- ids: array (nullable = true) | |-- element: map (containsNull = true) | | |-- key: integer | | |-- value: string (valueContainsNull = true) |-- match: array (nullable =

我正在使用Spark Scala API。我有一个Spark SQL数据帧(从Avro文件读取),具有以下模式:

root
|-- ids: array (nullable = true)
|    |-- element: map (containsNull = true)
|    |    |-- key: integer
|    |    |-- value: string (valueContainsNull = true)
|-- match: array (nullable = true)
|    |-- element: integer (containsNull = true)
基本上有两列[id:List[Map[Int,String]],match:List[Int]]。示例数据如下所示:

[List(Map(1 -> a), Map(2 -> b), Map(3 -> c), Map(4 -> d)),List(0, 0, 1, 0)]
[List(Map(5 -> c), Map(6 -> a), Map(7 -> e), Map(8 -> d)),List(1, 0, 1, 0)]
...
我想做的是
flatMap()
每行生成3列[id属性匹配]。使用上述两行作为输入数据,我们将得到:

[1,a,0]
[2,b,0]
[3,c,1]
[4,d,0]
[5,c,1]
[6,a,0]
[7,e,1]
[8,d,0]
...
然后
groupBy
字符串
属性(例如:a,b,…)生成
计数(“属性”)
总和(“匹配”)

我想做一些类似的事情:

val result = myDataFrame.select("ids","match").flatMap( 
    (row: Row) => row.getList[Map[Int,String]](1).toArray() )
result.groupBy("property").agg(Map(
    "property" -> "count",
    "match" -> "sum" ) )

问题在于
flatMap
将数据帧转换为RDD。有没有一种好方法可以使用数据帧执行
flatMap
类型操作,然后执行
groupBy

我的SQL有些生疏,但有一个选项是在flatMap中生成行对象列表,然后您可以将生成的RDD转换回数据帧。

flatMap
做什么?它将每个输入行转换为0或更多行。它可以过滤掉它们,也可以添加新的。在SQL中获得与您使用的
join
相同的功能。你能用
加入
做你想做的事吗

或者,您也可以查看
Dataframe.explode
,它只是一种特定的
join
(通过将数据帧连接到UDF,您可以轻松地创建自己的
explode
explode
将单个列作为输入,并允许您将其拆分或转换为多个值,然后将原始行连接回新行。因此:

user      groups
griffin   mkt,it,admin
可能成为:

user      group
griffin   mkt
griffin   it
griffin   admin
所以我想说,看看
DataFrame.explode
,如果这不容易实现,请尝试使用UDF进行连接

`myDataFrame.select(explode('ids as "ids",'match).
select( 'ids, explode('match as "match").
map ( r => {
val e=r.getMap[Int,String](0).head
(e._1,e._2,r.getInt(1))
}
)`

群比。。。。。可以在后面运行

谢谢您的回答!DataFrame.explode方法正是我想要的。
`myDataFrame.select(explode('ids as "ids",'match).
select( 'ids, explode('match as "match").
map ( r => {
val e=r.getMap[Int,String](0).head
(e._1,e._2,r.getInt(1))
}
)`