При использовании numpy самый быстрый способ сделать что-либо - обычно использовать трансляцию или векторизацию. Вы можете прочитать больше об этом здесь , но в основном это означает применение функции к массиву данных одновременно, а не итерацию по массиву с использованием for-l oop.
Возможно, это было то, на что вы ссылались, когда говорили о понимании списков, но в глубине души это просто другой способ написания циклов for.
Функция, которую вы ищете в этом case равен np.cumsum()
, используя axis=0
, чтобы указать, что мы хотим суммировать по каждому столбцу. Это векторизованный метод применения логи c, который вы ищете, и он будет намного быстрее, чем ваше решение for-l oop на больших матрицах.
>>> A = np.array([[0,0,0],[4,5,6],[7,8,9],[10,11,12]])
>>> np.cumsum(A, axis=0)
array([[ 0, 0, 0],
[ 4, 5, 6],
[11, 13, 15],
[21, 24, 27]], dtype=int32)
Ниже приведен график, показывающий сравнение скорости этого подхода и подхода в вашем вопросе, когда размер матрицы увеличивается, что показывает, что векторизованный подход имеет тенденцию быть примерно в 10 000 раз быстрее.
Код для генерации:
import perfplot
import numpy as np
def cdjb_cumsum(A):
return np.cumsum(A, axis=0)
def ajbg_forloop(A):
L = np.array(np.zeros((int(len(A)),int(len(A[0])))))
for r in range(0, len(L)):
L[r] = [sum([row[i] for row in A[0:r+1]]) for i in range(0,len(A[0]))]
return L
perfplot.show(
setup=lambda n: np.random.rand(n, n),
n_range=[2**k for k in range(20)],
kernels=[
cdjb_cumsum, ajbg_forloop
],
xlabel='Size of Array (n*n)',
)