Манипуляция научным набором данных в 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, будут высоко оценены.
Ответы
Ответ 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);
а
(reshape '(24 360 720) r)