Манипуляция научным набором данных в 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)