Можно ли ускорить расчет очень больших массивов в numpy? - PullRequest
0 голосов
/ 02 марта 2020

Я огляделся, но не смог найти точного ответа.

У меня есть несколько матриц 1200x2000, которые я хочу сохранить таким образом, чтобы потом их можно было прочитать в некотором роде l oop , Когда я хочу сохранить 100 из этих матриц, используя метод, описанный ниже, процесс действительно быстрый. Но если я хочу сохранить 1000, время, необходимое для каждой итерации, становится действительно длинным.

Вот пример проблемы (здесь матрицы только 1 с, потому что проблема уже появляется в этом простом случае):

reps = 1000
ret100 = np.zeros([1200, 2000, reps])
for k in range(reps):
    ret100[:,:,k] = 1
    print(k)

по сравнению с тем же, но повторений = 100:

reps = 100
ret100 = np.zeros([1200, 2000, reps])
for k in range(reps):
    ret100[:,:,k] = 1
    print(k)

У меня есть два вопроса:

  1. Почему каждый шаг в итерации выше займет больше времени, когда повторения = 1000, по сравнению с 100? Это ожидаемое поведение?
  2. Есть ли лучший способ хранить несколько матриц, чем представленный выше?

Ответы [ 2 ]

4 голосов
/ 02 марта 2020

Вы обращаетесь к ячейкам в памяти очень неэффективным способом. Вот простой тест, чтобы понять, почему:

a = np.zeros([1200, 2000, 100])
a[1,:,:] = 1 # time: 97.3 µs
a[:,1,:] = 1 # time: 345 µs
a[:,:,1] = 1 # time: 16 ms

Шаблон доступа к значениям первых измерений не эффективен. Это потому, что ячейки последнего измерения хранятся в памяти непрерывно , в отличие от других. Доступ к памяти несмежным способом, как правило, намного медленнее (чем больше шаг, тем медленнее он).

Поэтому рассмотрите возможность замены порядка измерений следующим образом:

reps = 100
ret100 = np.zeros([reps, 2000, 1200])
for k in range(reps):
    ret100[k,:,:] = 1
    print(k)

Это более чем в 10 раз быстрее на моей машине. Ускорение будет еще больше на больших массивах (например, с повторениями, установленными на 1000).

0 голосов
/ 02 марта 2020

Я не уверен, если это то, что вы хотите, пожалуйста, поправьте меня, если я неправильно понимаю.

import numpy as np
reps = 1000
ret100 = np.zeros([1200, 2000, reps])
ret100[:,:,0:reps] = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...