Как использовать Spark SQL DataFrame с flatMap?
я использую API Spark Scala. У меня есть Spark SQL DataFrame (чтение из файла Avro) со следующей схемой:
root
|-- ids: array (nullable = true)
| |-- element: map (containsNull = true)
| | |-- key: integer
| | |-- value: string (valueContainsNull = true)
|-- match: array (nullable = true)
| |-- element: integer (containsNull = true)
по существу 2 столбца [ ids: 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, свойства, матч]. Используя приведенные выше 2 строки в качестве входных данных мы получить:
[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
на String
свойства (например: a, b,...) для производства count("property")
и sum("match")
:
a 2 0
b 1 0
c 2 2
d 2 0
e 1 1
Я хотел бы сделать что-то вроде:
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
использование фреймов данных?
2 ответов
что значит flatMap
вы этого хотите? Он преобразует каждую входную строку в 0 или более строк. Он может отфильтровать их или добавить новые. В SQL, чтобы получить ту же функциональность, которую вы используете join
. Можете ли вы сделать то, что вы хотите сделать с join
?
кроме того, вы также можете посмотреть Dataframe.explode
, который является своеобразной join
(вы можете легко создать свой собственный explode
путем присоединения фрейма данных к UDF). explode
принимает один столбец в качестве входных данных и позволяет разделять его или преобразуйте его в несколько значений, а затем join
исходная строка возвращается в новые строки. Итак:
user groups
griffin mkt,it,admin
может стать:
user group
griffin mkt
griffin it
griffin admin
поэтому я бы сказал, взгляните на DataFrame.explode
и если это не поможет вам легко, попробуйте присоединиться к UDFs.
мой SQL немного ржавый, но один из вариантов в вашем flatMap для создания списка объектов строк, а затем вы можете преобразовать полученный RDD обратно в фрейм данных.