2012-02-18 12 views
2

いくつかの統計を検索するためにいくつかのベクトルを集計する必要があるという問題があります。たとえば、私は倍精度のベクトルを持っており、それらを合計する必要があります。私のベクトルは次のようになります:Hadoop:キーと値のペアの値としてdoubleの配列を持つにはどうしたらいいですか?

 1,0,3,4,5 
     2,3,4,5,6 
     3,4,5,5,6 

これまでの私のキーと値のペアは、(String、String)です。しかし、これらのベクトルを追加する必要があるたびに、まずそれらを二重配列に変換して追加し、最終的に集約ベクトルを文字列に変換する必要があります。私はちょうどフォームのキーと値のペアを持つことができればもっと速くなると思います(String、double array)。それらを前後に変換する必要はありません。私の問題は、二重配列を値として持つ方法を見つけることができないということです。新しいカスタムタイプを作成するのではなく、簡単な方法はありますか?

+0

なぜできないのですか?あなたは何を試しましたか? –

+0

私はTextとWritableを拡張している他のプリミティブ型でしか作業していません。私は配列を扱っていません。 – jojoba

答えて

3

このような意味ですか?

Map<String, List<Double>> arrays = new HashMap<String, List<Double>>(); 

double[] array; 
arrays.put("ArrayKey", Arrays.asList(array)); 

その後、あなたはマップ・メソッドを呼び出すことができます。

map(String key, String arrayKey) { 
    List<Double> value = arrays.get(arrayKey); 
} 

また、あなたがあなたのdouble配列をシリアル化し、それをバックデシリアライズすることができます

package test; 

import org.apache.commons.codec.binary.Base64InputStream; 
import org.apache.commons.codec.binary.Base64OutputStream; 

import java.io.*; 
import java.util.Arrays; 

public class Test { 

    public static void main(String[] args) throws IOException, ClassNotFoundException { 
     double[] array = {0.0, 1.1, 2.2, 3.3}; 
     String stringValue = serialize(array); 
     map("Key", stringValue); 
    } 

    public static void map(String key, String value) throws ClassNotFoundException, IOException { 
     double[] array = deserialize(value); 
     System.out.println("Key=" + key + "; Value=" + Arrays.toString(array)); 
    } 

    public static String serialize(double[] array) throws IOException { 
     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
     Base64OutputStream base64OutputStream = new Base64OutputStream(byteArrayOutputStream); 
     ObjectOutputStream oos = new ObjectOutputStream(base64OutputStream); 
     oos.writeObject(array); 
     oos.flush(); 
     oos.close(); 
     return byteArrayOutputStream.toString(); 
    } 

    public static double[] deserialize(String stringArray) throws IOException, ClassNotFoundException { 
     ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(stringArray.getBytes()); 
     Base64InputStream base64InputStream = new Base64InputStream(byteArrayInputStream); 
     ObjectInputStream iis = new ObjectInputStream(base64InputStream); 
     return (double[]) iis.readObject(); 
    } 
} 

OUTPUT:

Key=Key; Value=[0.0, 1.1, 2.2, 3.3] 

マッピングは高速ですが、あなたはそのために、ノードやクラスタを使用する場合(あなたが別のJVMにあなたの配列を渡す必要がある場合)erializationがより便利になります。

private static class SpeedTest { 
     private static final Map<String, List> arrays = new HashMap<String, List>(); 

     public static void test(final double[] array) throws IOException, ClassNotFoundException { 
      final String str = serialize(array); 
      final int amount = 10 * 1000; 

      long timeStamp = System.currentTimeMillis(); 
      for (int i = 0; i < amount; i++) { 
       serialize(array); 
      } 
      System.out.println("Serialize: " + (System.currentTimeMillis() - timeStamp) + " ms"); 

      timeStamp = System.currentTimeMillis(); 
      for (int i = 0; i < amount; i++) { 
       deserialize(str); 
      } 
      System.out.println("Deserialize: " + (System.currentTimeMillis() - timeStamp) + " ms"); 

      arrays.clear(); 
      timeStamp = System.currentTimeMillis(); 
      // Prepaire map, that contains reference for all arrays. 
      for (int i = 0; i < amount; i++) { 
       arrays.put("key_" + i, Arrays.asList(array)); 
      } 
      // Getting array by its key in map. 
      for (int i = 0; i < amount; i++) { 
       arrays.get("key_" + i).toArray(); 
      } 
      System.out.println("Mapping: " + (System.currentTimeMillis() - timeStamp) + " ms"); 
     } 
    } 

OUTPUT:

Serialize: 298 ms 
Deserialize: 254 ms 
Mapping: 27 ms 
+0

いいえ、私は構造のためではなく、ハーフープのキーと値のペアを意味します。 hadoopのキー値は、マップタスクが還元タスクに渡すものです。 – jojoba

+0

@jojoba私の編集を参照してください。 – kornero

+0

hmm..thisは非常に面白そうです...私は私の問題を解決するために最後の数時間を試しています。私はやったことが十分に効率的だったようです...あなたの答えは私が持つかもしれない別の問題を解決します。これらのシリアライズ関数とデシリアライズ関数は、文字列を二重配列に前後に変換する効率的な方法ですか? (私の前の質問に申し訳ありません、おそらく私は問題の十分なヒントを書いていませんでした) – jojoba