2012-02-18 3 views
2

일부 통계를 찾기 위해 일부 벡터를 집계해야하는데 문제가 있습니다. 예를 들어 나는 복식의 벡터를 가지고 있으며이를 합계해야합니다. 내 벡터 모양은 다음과 같습니다.Hadoop : 키 - 값 쌍의 값으로 두 배 배열을 가질 수 있습니까?

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

내 키 - 값 쌍은 (String, String)입니다. 그러나 이러한 벡터를 추가해야 할 때마다 먼저 두 개의 배열로 변환하고이를 더하고 마지막으로 집계 벡터를 문자열로 변환해야합니다. 만약 내가 단지 형식 (문자열, 더블 배열)에서 키 - 값 쌍을 가질 수있는 것이 훨씬 더 빠를 것이라고 생각합니다. 그들을 앞뒤로 변환 할 필요가 없습니다. 내 문제는 이중 배열을 값으로 갖는 방법을 찾을 수 없다는 것이다. 새로운 사용자 정의 유형을 만드는 것보다 쉬운 방법이 있습니까?

+0

왜 못해? 너 뭐 해봤 니? –

+0

나는 Writable을 확장하는 Text 및 기타 기본 유형으로 만 작업했습니다. 나는 배열을 다루지 않았다. – jojoba

답변

3

이런 뜻입니까?

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

은 또한 당신이 당신의 이중 배열을 직렬화 할 수 있으며, 다음을 다시 역 직렬화 :

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

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

는 당신은 방법을지도 부를 수

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(); 
    } 
} 

출력 :

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"); 
     } 
    } 

출력 :

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

아니요. 구조가 아니라, hadoop의 키 - 값 쌍을 의미합니다. hadoop의 키 - 값은 맵 태스크가 reduce 태스크에 전달하는 것입니다. – jojoba

+0

@jojoba 내 편집 내용보기. – kornero

+0

음 ...이게 아주 재미있어 보이네. 내 문제를 해결하기 위해 지난 몇 시간 동안 노력하고있어. 내가 한 일은 충분히 효율적이라고 생각해. 네 대답이 내가 가진 다른 문제를 해결해. 이 serialize 및 deserialize 함수는 문자열을 이중 배열로 앞뒤로 변환하는 효율적인 방법입니까? (내 이전 질문에 대한 사과, 아마도 내 문제에 대한 충분한 힌트를 작성하지 않았다) – jojoba

관련 문제