Wie berechne Perzentil der Spalte in einen DataFrame in der Funke?
Ich versuche zu berechnen Perzentil einer Spalte in einem DataFrame? Ich kann nicht finden, percentile_approx Funktion in der Funke-aggregation-Funktionen.
Z.B. im Hive-wir haben percentile_approx und wir können es verwenden, in der folgenden Weise
hiveContext.sql("select percentile_approx("Open_Rate",0.10) from myTable);
Aber ich will es tun, mit Funken DataFrame aus performance-Gründen.
Beispiel-Datensatz
|User ID|Open_Rate|
-------------------
|A1 |10.3 |
|B1 |4.04 |
|C1 |21.7 |
|D1 |18.6 |
Ich soll herausfinden, wie viele Benutzer fallen in 10% - Perzentil oder 20% - Perzentil und so weiter. Ich möchte so etwas wie dies tun
df.select($"id",Percentile($"Open_Rate",0.1)).show
- Es gibt keine performance-Unterschied zwischen der Verwendung von SQL-Abfragen und-DataFrame - beide verwenden die gleiche Ausführung-Motor.
- Sie können Ihre eigenen UDAF. Das ist, wie ich es getan habe : stackoverflow.com/a/51859138/2166220
Du musst angemeldet sein, um einen Kommentar abzugeben.
Seit Spark2.0 sind die Dinge immer einfacher,benutzen Sie einfach diese Funktion in DataFrameStatFunctions wie :
df.stat.approxQuantile("Open_Rate",Array(0.25,0.50,0.75),0.0)
Gibt es auch einige nützliche Statistik-Funktionen für DataFrame in DataFrameStatFunctions.
percentile_approx
was ist ein Funken-sql-Funktion. Es wird ein Integer-argument optional ist bezogen auf die Anzahl der Beobachtungen pro Gruppe: standardmäßig 10.000 Euro. Dies bedeutet, dass diese Funktion liefert die exakte Perzentile für Gruppen mit weniger als 10.000 Beobachtungen. Geben Sie einen größeren Wert für mehr Präzision.SparkSQL und der Scala dataframe/dataset-APIs ausgeführt werden, die von den gleichen Motor. Entsprechenden Vorgänge generieren, die äquivalente Ausführungspläne. Sehen Sie die Ausführungspläne mit
explain
.Wenn es um Ihre konkrete Frage, es ist ein gemeinsames Muster zu vermischen SparkSQL und Scala DSL-syntax, weil, wie Sie entdeckt haben, Ihre Fähigkeiten sind noch nicht entspricht. (Ein weiteres Beispiel ist der Unterschied zwischen SQL
explode()
- und DSLexplode()
letztere mächtiger, aber auch ineffizienter durch marshalling.)Den einfachen Weg, es zu tun ist wie folgt:
Was müssen Sie beachten, wenn Sie gehen mit der einfachen Methode ist, dass die temporäre Tabelle, die Namen sind cluster-global (bis zu 1.6.x). Daher sollten Sie randomisierten Tabelle Namen, wenn Sie den code ausführen kann gleichzeitig mehr als einmal auf den gleichen cluster.
Auf mein team, das Muster ist Häufig genug, dass wir Hinzugefügt haben, eine
.sql()
implizitDataFrame
die automatisch registriert, und dann hebt die Registrierung einer temp-Tabelle für den Umfang der SQL-Anweisung.