Научные манипуляции с наборами данных в Clojure - чтение ByteBuffers в матрицы - PullRequest
10 голосов
/ 01 февраля 2011

Я собираюсь использовать 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 Ответ

6 голосов
/ 02 февраля 2011

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

в качестве * * +1010

(reshape '(24 360 720) r)
...