복붙노트

[HADOOP] Hadoop : 키-값 쌍의 값으로 double 배열을 어떻게 가질 수 있습니까?

HADOOP

Hadoop : 키-값 쌍의 값으로 double 배열을 어떻게 가질 수 있습니까?

통계를 찾기 위해 일부 벡터를 집계 해야하는 문제가 있습니다. 예를 들어 나는 복식의 벡터를 가지고 있으며 그것들을 합산해야합니다. 내 벡터는 다음과 같습니다

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

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

해결법

  1. ==============================

    1.이런 뜻인가요?

    이런 뜻인가요?

    Map<String, List<Double>> arrays = new HashMap<String, List<Double>>();
    
    double[] array;
    arrays.put("ArrayKey", Arrays.asList(array));
    

    그런 다음 map 메소드를 호출 할 수 있습니다.

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

    또한 이중 배열을 직렬화 한 다음 역 직렬화 할 수 있습니다.

    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으로 전달해야하는 경우).

     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
    
  2. from https://stackoverflow.com/questions/9342243/hadoop-how-can-i-have-an-array-of-doubles-as-a-value-in-a-key-value-pair by cc-by-sa and MIT license