2016-07-10 11 views
0

Ich habe eine pairRDD mit Tupeln in der folgenden Form sein:Konvertieren einer RDD in ein Schlüsselwertpaar RDD, wobei die Werte in einer Liste sein

[(1,"b1","c1","d1","e1"), (2,"b2","c2","d2","e2"), ... 

Was ich will, ist, die oben in einen Schlüssel zu verwandeln -Wertpaar RDD, wobei das erste Feld der Schlüssel und das zweite Feld eine Liste von Strings (Wert) ist. das heißt ich will es auf die Form drehen:

[(1,["b1","c1","d1","e1"]), (2,["b2","c2","d2","e2"]), ... 

Danach ist es dann möglich, ein beliebiges Feld zuzugreifen, die ich will?

Zum Beispiel, kann ich auf das Tupel (1,["b1","c1","d1","e1"]) zugreifen, dann nur das Feld d1 extrahieren?

+0

Dies sieht aus wie eine 'HashMap >' oder 'LinkedHashMap >' Wenn Sie die Schlüssel 'Reihenfolge zu erhalten möchten. – Titus

+0

sollte ich rdd.hashMap verwenden? – hammad

+0

Oh, ich habe missverstanden, ich dachte, Sie wollten ein RDD-Objekt in ein normales Java-Objekt konvertieren, als RDD-Objekt können Sie 'JavaPairRDD >' verwenden. – Titus

Antwort

1

Wenn Sie eine RDD mit Tuples haben, die Tupel jedoch dargestellt werden, können Sie mapToPair verwenden, um Ihre RDD von Tuple in ein PairRDD mit Schlüssel und Wert wie gewünscht umzuwandeln.

In Java 8 könnte

JavaPairRDD<Integer,List<String>> r = 
    rddOfTuples.mapToPair((t)->new Tuple2(
     extractKey(t), 
     extractTuples(t) 
)); 

Hinweis sein, dass dieser Vorgang einen Shuffle vorstellen.

Um das Offensichtliche zu sagen, sind extractKey und extractTuples Methoden zu implementieren, die Teile des ursprünglichen Tupels wie benötigt extrahieren.

Mit meiner begrenzten Kenntnis der Scala Tupeln, und der Eingang unter der Annahme, ist so etwas wie scala.Tuple5<String,Integer,Integer,Integer,Integer>, könnte dies sein:

JavaPairRDD<Integer,List<String>> r = 
    rddOfTuples.mapToPair((t)->new Tuple2(
     t._1, 
     Arrays.asList(t._2,t._3,t._4,t._6) 
)); 

Wenn aber Sie wissen nicht, vorher die arity (Anzahl der Elemente) Ihrer Tuple dann, in Scala ausgedrückt, ist es ein Product. Um Ihre Elemente dynamisch zugreifen zu können, müssen Sie die Product Schnittstelle verwenden, mit einer Auswahl von:

  • int productArity()
  • Object productElement(int n)
  • Iterator<Object> productIterator()

Dann wird es eine regelmäßige Java Übung:

JavaPairRDD<Integer,List<String>> r = 
    rddOfTuples.mapToPair((t)->{ 
    List<String> l = new ArrayList<>(t.productArity()-1); 
    for (int i = 1; i < t.productArity(); i++) { 
     l.set(i-1,t.productElement(i)); 
    } 
    return new Tuple2<>(t._1,l); 
    })); 

Ich hoffe ich habe Es ist alles in Ordnung ... dieser Code oben ist ungetestet/nicht kompiliert ... Wenn Sie es mit Korrekturen arbeiten lassen, dann wenden Sie die Korrekturen in dieser Antwort an ...

+0

aber das Problem hier ist, dass ich will den Wert als eine Liste – hammad

+0

bedeutet das Tuple ll definiert werden als (1, ["hh", "gg", "hh"]) und 1 hier steht der Schlüssel – hammad

+0

wold Sie ändern Code bitte, um mir zu zeigen, wie es geht? – hammad

1

Sie könnten versuchen, eine Karte zu verwenden Funktion, zB in Scala:

rdd.map { case (k,v1,v2,v3,v4) => (k,(v1,v2,v3,v4)) } 

Oder rdd.groupBy könnte auch verwendet werden, aber dies ineffizient auf große Datenmengen sein könnte.

+0

ich benutze Java – hammad

+0

Wie kann ich es in Java tun – hammad

+0

Ich bin nicht so vertraut mit der Verwendung von Spark in Java, aber dieser Code könnte helfen: http: // www.programcreek.com/java-api-examples/index.php?source_dir=oryx-master/app/oryx-app-mllib/src/main/java/com/cloudera/oryx/app/batch/mllib/als/ Evaluation.java - Sie können eine Funktion erstellen, die Tuple5 als Eingabe akzeptiert und ein Tuple2 zurückgibt > –

Verwandte Themen