2015-06-03 2 views
9

Dies ist wahrscheinlich ein einfaches Problem, aber im Grunde habe ich einen Datensatz, wo ich die Anzahl der Frauen für jedes Land zählen soll. Letztendlich möchte ich jede Zählung nach dem Land gruppieren, aber ich bin nicht sicher, was ich für den Wert verwenden soll, da es in der Datenmenge keine Zählungsspalte gibt, die ich als Wert in einem groupByKey oder reduceByKey verwenden kann. Ich dachte an eine reduceByKey(), aber das erfordert ein Schlüssel-Wert-Paar, und ich möchte nur den Schlüssel zählen und einen Zähler als Wert machen. Wie gehe ich vor?Spark - Wie die Anzahl der Datensätze nach Schlüssel zu zählen

val lines = sc.textFile("/home/cloudera/desktop/file.txt") 
val split_lines = lines.map(_.split(",")) 
val femaleOnly = split_lines.filter(x => x._10 == "Female") 

Hier ist, wo ich feststecke. Das Land ist ebenfalls Index 13 im Datensatz. Die Ausgabe sollte so aussehen: (Australien, 201000) (Amerika, 420000) usw. Jede Hilfe wäre toll. Dank

+0

Gibt es einen Grund Warum möchten Sie (vorübergehend) keinen Wert hinzufügen? Sie können es im Wesentlichen wie Word Count und machen Sie alle Ihre KV-Paare so etwas wie dann ReduceByKey und summieren Sie die Werte. Oder mache den Schlüssel <[female, australia], 1> und reduziere dannByKey und sum, um die Anzahl der Frauen im angegebenen Land zu ermitteln. Ich bin nicht sicher, wie man das mit Scala macht, aber mit Python + Spark ist das sehr einfach. – TravisJ

Antwort

12

Sie sind fast da! Alles, was Sie brauchen, ist eine countByValue:

val countOfFemalesByCountry = femaleOnly.map(_(13)).countByValue() 
// Prints (Australia, 230), (America, 23242), etc. 

(In Ihrem Beispiel ich nehme an, Sie bedeuten x (10) statt x._10)

Alle zusammen:

sc.textFile("/home/cloudera/desktop/file.txt") 
    .map(_.split(",")) 
    .filter(x => x(10) == "Female") 
    .map(_(13)) 
    .countByValue() 
+0

das ist eine gute Antwort. Wie kann ich hashmap einer hashmap berechnen. Das wäre ich möchte die Gruppierung für jeden Sex haben. So etwas wie sc.textFile ("/ home/cloudera/desktop/file.txt") .map (_. Split (",")) .map (_ (10)) .map (_ (13)) .countByValue() – user1579557

0

Sie können einfach einen Schlüssel erstellen, es muss nicht in der Datei/Datenbank sein. Zum Beispiel:

val countryGender = sc.textFile("/home/cloudera/desktop/file.txt") 
       .map(_.split(",")) 
       .filter(x => x._10 == "Female") 
       .map(x => (x._13, x._10)) // <<<< here you generate a new key 
       .groupByKey(); 
+0

Können Sie dies mit einer Reduzierungsfunktion beenden, um die Anzahl der Datensätze nach Ländern zu ermitteln? –

5

Haben Sie darüber nachgedacht Ihre RDD mit der Dataframes API Manipulation?

Es sieht so aus, als ob Sie eine CSV-Datei laden, die Sie mit spark-csv machen können.

Dann ist es eine einfache Sache (wenn Ihre CSV mit den offensichtlichen Spaltennamen betitelt ist) von:

import com.databricks.spark.csv._ 

val countryGender = sqlContext.csvFile("/home/cloudera/desktop/file.txt") // already splits by field 
    .filter($"gender" === "Female") 
    .groupBy("country").count().show() 

Wenn Sie in dieser Art von Manipulation tiefer gehen wollen, hier ist der Führer: https://spark.apache.org/docs/latest/sql-programming-guide.html