Scala пытается извлечь значение из массива udt в пределах фрейма данных - PullRequest
0 голосов
/ 26 марта 2020

Похоже, это должен быть простой вопрос, но я не могу найти ничего, что будет работать в документации или здесь, в stackoverflow.

Я пытаюсь извлечь значение из udt в пределах фрейма данных в унаследованном Scala коде. Моя цель - иметь DataFrame со столбцом для подгонки, который извлекается из yProbability.values(1) (или любого другого правильного синтаксиса в Scala)

Структура данных имеет следующую структуру:

outputDataAAL:org.apache.spark.sql.DataFrame
 - info_conversationid:string 
 - document:string 
 - yProbability:udt
 - yHat:double

Пример элемента yProbability:

array
 - 0: 1
 - 1: 2
 - 2: []
 - 3:
     - 0: 0.8054468196483193
     - 1: 0.19455318035168068

В r я делаю простое:

outputDataAAL$fit <- outputDataAAL$yProbability %>% lapply(function(x) {x[[2]][2]}) %>% unlist

Это просто, но медленно для размеров данных. смотря на. Вот почему я хотел бы сделать это в Scala.

Я попытался извлечь только значения (это элемент массива № 3 в yProbability), но оба эти следующих метода дают мне ошибку ниже.

val newSample = outputDataAAL.select("yProbability.values(1)")
val newSample = outputDataAAL.select($"yProbability".getItem("values(1)"))

Ошибка:

Can't extract value from yProbability#4404: need struct type but got 
struct<type:tinyint,size:int,indices:array<int>,values:array<double>>

Я также пытался сэмплировать outputDataAAL на #4404, сбил меня с толку, и я не знал, было ли это из-за плохого столбца , Очевидно, не повезло.

Большое спасибо за вашу помощь.

-Рик

1 Ответ

0 голосов
/ 27 марта 2020

Ну, я нашел решение, но оно немного уродливо. Я чувствую, что должен быть более простой ответ, но это работает.

import org.apache.spark.sql.functions._
import org.apache.spark.ml._
val vecToArray = udf( (xs: linalg.Vector) => xs.toArray )  
val newSample = outputDataAAL.withColumn("yProbabilityArr" , vecToArray($"yProbability") )
val outputDataAALNew = newSample.withColumn("fit", $"yProbabilityArr".getItem(1))
...