2017-05-05 6 views
0

Ich brauche eine benutzerdefinierte Funktion mit einem bestimmten Typen als EingängeWie verwende ich den benutzerdefinierten Typ in der benutzerdefinierten Funktion?

spark.udf.register("udf", (p:Point) => distance(p.x, p.y)) 

ich einen Punkt Fallklasse

erstellt schreiben
case class Point(val x: Double, val y: Double) 

Als ich die UDF in einer SQL-Abfrage verwenden, ist es nicht funktioniert . Irgendeine Hilfe?

+0

In SQL-Abfrage, ist "Point" -Typ verfügbar? Aufruf UDF müssen Sie Spalte übergeben, die Datentyp hat als "Point" –

+0

No Point Typ existiert nicht, wie man es definiert? – syl

Antwort

0

Ich kenne Ihre genaue Anforderung nicht, aber mit Blick auf Ihren Code, ich schlage eine Logik vor.

Hoffnung Abfrage/Tabelle zwei separate Werte wie X und Y haben Sie Ihre UDF wie unten reframe können

spark.udf.register("udf", (x:Double, y:Double) => distance(x,y)) 

Jetzt können Sie neue verwenden UDF withCoumn() mit und zwei separate Parameter X und Y passieren

Lassen Sie mich wissen, etwas anderes wird erwartet.

+0

@syl Bitte machen Sie die Antwort als richtig, wenn es für Sie funktioniert –

1

Definieren Sie Ihre Fallklasse und verwenden Sie sie als "Quelle" des Schemas für Ihre Datasets.

case class Point(val x: Double, val y: Double) 
val points = Seq(Point(0,0), Point(0,1)).toDF 
scala> points.show 
+---+---+ 
| x| y| 
+---+---+ 
|0.0|0.0| 
|0.0|1.0| 
+---+---+ 

Wie Sie vielleicht bemerkt haben, wird die Fallklasse zu einem bloßen Schema (d. H. Struktur) Ihres Datasets. Mit anderen Worten, Sie können keine benutzerdefinierte Funktion schreiben, die während der Verarbeitung solcher Datensätze Point Objekte akzeptiert.

Eine mögliche Lösung besteht nicht darin, eine benutzerdefinierte Funktion zu verwenden, sondern Dataset einzugeben und die Funktion nicht als benutzerdefinierte Funktion, sondern als reguläre Scala-Funktion (oder Methode) zu registrieren.

scala> val points = Seq(Point(0,0), Point(0,1)).toDS 
points: org.apache.spark.sql.Dataset[Point] = [x: double, y: double] 

def distance(x: Double, y: Double) = y - x 
val myFn = (p:Point) => distance(p.x, p.y) 
scala> points.map(myFn).show 
+-----+ 
|value| 
+-----+ 
| 0.0| 
| 1.0| 
+-----+ 
Verwandte Themen