Numpy.mean, amin, amax, std огромные доходы - PullRequest
4 голосов
/ 05 августа 2011

Я изо всех сил стараюсь работать с большими массивами.Вот сценарий.Я работаю с изображениями размером 300–950 МБ и использую GDAL для чтения их как массивов Numpy.Чтение в массиве использует ровно столько памяти, сколько можно было ожидать, т.е.250 МБ для изображения 250 МБ и т. Д. *

Моя проблема возникает, когда я использую numpy для получения среднего, минимального, максимального или стандартного отклонения.В main () я открываю изображение и читаю массив (типа ndarray).Затем я вызываю следующую функцию, чтобы получить стандартное отклонение для двумерного массива:

def get_array_std(input_array):
    array_standard_deviation = numpy.std(input_array, copy=False)
    return array_standard_deviation

Здесь у меня постоянно возникают ошибки памяти (на машине 6 ГБ).Из документации похоже, что numpy возвращает ndarray с той же формой и dtype, что и мой ввод, тем самым удваивая объем памяти.

Использование:

print type(array_standard_deviation)

Возвращает:

numpy.float64

Дополнительно, используя:

print array_standard_deviation

Возвращает тип с плавающей запятой, как и следовало ожидать.Numpy читает массив снова, чтобы выполнить этот расчет?Буду ли я лучше перебирать массив и вручную выполнять вычисления?Как насчет работы со сплющенным массивом?

Я попытался поместить каждый статистический вызов (numpy.amin (), numpy.amax (), numpy.std (), numpy.mean ()) в их собственную функциютак что большой массив вышел бы из области видимости, но не повезло.Я также пытался использовать приведение к другому типу, но без радости.

Ответы [ 3 ]

4 голосов
/ 03 ноября 2011

Numpy делает «наивное» сокращение для стандартного ввода.Это довольно неэффективно памяти.Посмотрите здесь для лучшей реализации: http://luispedro.org/software/ncreduce

1 голос
/ 12 октября 2011

Вы уверены, что это проблема со всеми статистическими функциями, которые вы пытаетесь, или это просто np.std?

Я пытался использовать следующий метод для воспроизведения этого:

  1. Запустите ipython -cs 0, импортируйте numpy как nd
  2. q = rand (5600,16000), предоставив мне большой большой тестовый массив.
  3. Наблюдайте за использованием памяти внешне во время np.mean (q), np.amin (q), np.amax (q), np.std (q)

Из них np.std значительно медленнее: для большинства функций требуется 0,2 секундына моем компьютере, в то время как стандартный берет 2.3.Хотя у меня нет точной утечки памяти, используемой вами памяти, она остается в основном постоянной при выполнении всего, кроме std, но удваивается при запуске std, а затем возвращается к исходному значению.

I 'Мы написали следующий модифицированный стандарт, который работает с блоками заданного числа элементов (я использую 100000):

def chunked_std( A, chunksize ):
    Aflat = A.ravel()
    Amean = A.mean()
    Alen = len(Aflat)

    i = np.concatenate( ( np.arange(0,Alen,chunksize), [Alen] ) )

    return np.sqrt(np.sum(np.sum(abs(Aflat[x:y]-Amean)**2) for (x,y) in zip(i[:-1],i[1:]))/Alen)

Это, похоже, значительно сокращает использование памяти, но также примерно в два раза быстрее, чемнормальный нп.стд для меня.Вероятно, существуют значительно более элегантные способы написания такой функции, но, похоже, это работает.

1 голос
/ 05 августа 2011

Не знаю, полезно ли это, но решает ли проблема использование метода массива?то есть

input_array.std()

вместо

numpy.std(input_array)

Проблема, которую вы описываете, не имеет большого смысла для меня;Я часто работаю с большими массивами, но не сталкиваюсь с ошибками при выполнении простых задач, подобных этим.Есть ли что-то еще, что вы делаете, что может в конечном итоге передать копии массивов вместо ссылок?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...