2011-02-01 2 views
10

Я ищу использовать Clojure и Incanter для обработки большого научного набора данных; в частности, 0,5-градусная версия this dataset (доступна только в двоичном формате).Научные манипуляции с данными в Clojure - чтение ByteBuffers в матрицы

Мой вопрос: какие рекомендации у вас есть для элегантных способов решения этой проблемы в Java/Clojure? Есть ли простой способ получить этот набор данных в Incanter или какой-либо другой пакет Java-матрицы?

мне удалось прочитать двоичные данные в java.nio.ByteBuffer, используя следующий код:

(defn to-float-array [^String str] 
    (-> (io/to-byte-array (io/to-file str)) 
     java.nio.ByteBuffer/wrap 
     (.order java.nio.ByteOrder/LITTLE_ENDIAN))) 

Теперь, я действительно борется с тем, как я могу начать манипулировать этой ByteBuffer как массив. Я использую Python's NumPy, который позволяет очень легко манипулировать этими огромными наборами данных. Вот код питона за то, что я ищу, чтобы сделать:

// reshape row vector into (time, lat_slices, lon_slices) 
// then cut out every other row 
rain_data = np.fromfile("path/to/file", dtype="f") 
rain_data = rain_data.reshape(24, 360, 720); 
rain_data = rain_data[0:23:2,:,:]; 

После нарезки, я хочу вернуть вектор из этих двенадцати массивов. (Мне нужно манипулировать ими отдельно, как будущие функциональные входы.)

Итак, любые советы о том, как получить этот набор данных в Incanter, будут высоко оценены.

+0

Вы когда-нибудь находили решение? Я нашел отличную функцию удобства, которая позволяет создавать буфер с отображением байт памяти в виде файла с одним слоем: https://github.com/pjstadig/nio (nio.core/mmap "/ path/to/file") , Я все еще пытаюсь понять, как читать это в матрицу jblas с правильной формой. – Peter

ответ

6

Я не знаю, как превратить ваш ByteBuffer в массив, но вот реализация функции reshape:

(defn reshape [v c] 
    (if (= (count v) 1) 
    c 
    (recur (butlast v) 
      (partition (last v) c)))) 

(Это прекрасно работает в моем ограниченном тестировании.) Если ваши данные в вектор r, то вы можете реализовать

rain_data = rain_data.reshape(24, 360, 720); 

в

(reshape '(24 360 720) r)