Java / Spark: как найти ключ с максимальным значением в столбце с массивом структуры карты - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть фрейм данных, и я хочу получить ключ с максимальным значением на карте.

создание фрейма данных:

Dataset<Row> data = spark.read()
                .option("header", "true")
                .option("inferSchema", "true")
                .csv("/home/path/to/file/verify.csv");
//loading Spark ML model
PipelineModel gloveModel = PipelineModel.load("models/gloveModel");
Dataset<Row> df = gloveModel.transform(data);

df.printSchema ();

 |-- id: integer (nullable = true)
 |-- description: string (nullable = true)
 |-- class: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- result: string (nullable = true)     
 |    |    |-- metadata: map (nullable = true)      
 |    |    |    |-- key: string
 |    |    |    |-- value: string (valueContainsNull = true)

// поле с записями карты выглядит следующим образом:

df.select ("class.metadata"). Show (10,50);

+-----------------------------------------------------------------------------------------------------------------+
|                                                                                                         metadata|
+-----------------------------------------------------------------------------------------------------------------+
|  [[Sports -> 3.2911853E-9, Business -> 5.1852658E-6, World -> 3.96135E-9, Sci/Tech -> 0.9999949, sentence -> 0]]|
|      [[Sports -> 1.9902605E-10, Business -> 1.0305631E-8, World -> 1.0, Sci/Tech -> 3.543277E-9, sentence -> 0]]|
|    [[Sports -> 1.0, Business -> 8.1944885E-12, World -> 4.554111E-13, Sci/Tech -> 1.7239962E-12, sentence -> 0]]|
+-----------------------------------------------------------------------------------------------------------------+

Я хотел бы добиться ниже результата (наибольшее значение в каждой карте строки):

+--------------+
|    prediction|
+--------------+
|      Sci/Tech|
|         World|
|        Sports|
+--------------+

Я пытался:

df.select (map_values ​​(col ( "class.metadata"))). show (10, 50); но в конечном итоге с ошибкой:

Exception in thread "main" org.apache.spark.sql.AnalysisException: cannot resolve 'map_values(`class`.`metadata`)' due to data type mismatch: argument 1 requires map type, however, '`class`.`metadata`' is of array<map<string,string>> type.;;
'Project [map_values(class#95.metadata) AS map_values(class.metadata)#106]...

df.select (flatten (col ("class"))). show (); с ошибкой:

Exception in thread "main" org.apache.spark.sql.AnalysisException: cannot resolve 'flatten(`class`)' due to data type mismatch: The argument should be an array of arrays, but '`class`' is of array<struct<annotatorType:string,begin:int,end:int,result:string,metadata:map<string,string>,embeddings:array<float>>> type.;;
'Project [flatten(class#95) AS flatten(class)#106]

My Spark SQL версия 2.4.0 (где функция разнесения устарела)

Любые предложения / советы приветствуются! Спасибо!

1 Ответ

0 голосов
/ 27 апреля 2020

class.metadata относится к типу Array типа Map. Но функция map_values принимает только тип карты.

Используйте explode, чтобы извлечь карту из массива данных и затем передать эти данные карты в функцию map_values. Пожалуйста, проверьте ниже.

import org.apache.spark.sql.functions.explode

df.select(explode($"class.metadata").as("metadata")).select(map_values($"metadata")).show(false)

...