2016-11-23 2 views
6

Ich benutze Spark 1.6.1, und ich habe solch einen Datenrahmen.Wie "Cube" nur für bestimmte Felder auf Spark Dataframe verwenden?

+-------------+-----------+-----------------+-------+-------+-------+----------+-------+-------+-------+-------+ 
|  scene_id| action_id|  classifier|os_name|country|app_ver| p0value|p1value|p2value|p3value|p4value| 
+-------------+-----------+-----------------+-------+-------+-------+----------+-------+-------+-------+-------+ 
| test_home|scene_enter|  test_home|android|  KR| 5.6.3|__OTHERS__| false| test| test| test| 
...... 

Und ich möchte Dataframe wie folgt mit Cube-Operation zu erhalten.

(von allen Feldern gruppierte, sondern nur „os_name“, „Land“, „app_ver“ Felder sind in Würfel geschnitten)

+-------------+-----------+-----------------+-------+-------+-------+----------+-------+-------+-------+-------+---+ 
|  scene_id| action_id|  classifier|os_name|country|app_ver| p0value|p1value|p2value|p3value|p4value|cnt| 
+-------------+-----------+-----------------+-------+-------+-------+----------+-------+-------+-------+-------+---+ 
| test_home|scene_enter|  test_home|android|  KR| 5.6.3|__OTHERS__| false| test| test| test| 9| 
| test_home|scene_enter|  test_home| null|  KR| 5.6.3|__OTHERS__| false| test| test| test| 35| 
| test_home|scene_enter|  test_home|android| null| 5.6.3|__OTHERS__| false| test| test| test| 98| 
| test_home|scene_enter|  test_home|android|  KR| null|__OTHERS__| false| test| test| test|101| 
| test_home|scene_enter|  test_home| null| null| 5.6.3|__OTHERS__| false| test| test| test|301| 
| test_home|scene_enter|  test_home| null|  KR| null|__OTHERS__| false| test| test| test|225| 
| test_home|scene_enter|  test_home|android| null| null|__OTHERS__| false| test| test| test|312| 
| test_home|scene_enter|  test_home| null| null| null|__OTHERS__| false| test| test| test|521| 
...... 

I wie unten versucht, aber es scheint langsam und hässlich zu sein ..

var cubed = df 
    .cube($"scene_id", $"action_id", $"classifier", $"country", $"os_name", $"app_ver", $"p0value", $"p1value", $"p2value", $"p3value", $"p4value") 
    .count 
    .where("scene_id IS NOT NULL AND action_id IS NOT NULL AND classifier IS NOT NULL AND p0value IS NOT NULL AND p1value IS NOT NULL AND p2value IS NOT NULL AND p3value IS NOT NULL AND p4value IS NOT NULL") 

Irgendwelche besseren Lösungen? Bitte execuse mein schlechtes Englisch .. ^^;

Vielen Dank im Voraus ..

+0

Danke, aber 'NULL' Werte wurden durch die' cube' Betrieb @CarlosVilchez ... –

Antwort

4

Ich glaube, Sie das Problem nicht vollständig vermeiden können, aber es ist ein einfacher Trick, den Sie ihr Ausmaß reduzieren. Die Idee ist, alle Spalten, die nicht marginalisiert werden sollen, durch einen einzigen Platzhalter zu ersetzen.

Zum Beispiel, wenn Sie eine haben DataFrame:

val df = Seq((1, 2, 3, 4, 5, 6)).toDF("a", "b", "c", "d", "e", "f") 

und Sie sind in Würfel interessiert den Rand gedrängt von d und e und gruppiert nach a..c Sie den Ersatz für a..c wie definieren:

import org.apache.spark.sql.functions.struct 
import sparkSql.implicits._ 

// alias here may not work in Spark 1.6 
val rest = struct(Seq($"a", $"b", $"c"): _*).alias("rest") 

und cube:

val cubed = Seq($"d", $"e") 

// If there is a problem with aliasing rest it can done here. 
val tmp = df.cube(rest.alias("rest") +: cubed: _*).count 

Schnellfilter und wählen Sie sollte den Rest erledigen:

tmp.where($"rest".isNotNull).select($"rest.*" +: cubed :+ $"count": _*) 

mit Ergebnis wie:

+---+---+---+----+----+-----+ 
| a| b| c| d| e|count| 
+---+---+---+----+----+-----+ 
| 1| 2| 3|null| 5| 1| 
| 1| 2| 3|null|null| 1| 
| 1| 2| 3| 4| 5| 1| 
| 1| 2| 3| 4|null| 1| 
+---+---+---+----+----+-----+ 
Verwandte Themen