Научные манипуляции с набором данных в Clojure, чтение ByteBuffers в матрицы

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

Мой вопрос: какие у вас есть рекомендации по элегантным способам решения этой проблемы в 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 NumPy, который позволяет очень легко манипулировать этими огромными наборами данных. Вот код Python для того, что я хочу сделать:

// 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, будут высоко оценены.


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


Ответы (1)


Я не знаю, как преобразовать ваш 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);

as

(reshape '(24 360 720) r)
person bdesham    schedule 01.02.2011