Почему numpy.var это O (N) пробел? - PullRequest
2 голосов
/ 19 мая 2019

У меня есть массив ~ 13 ГБ.Я называю numpy.var на нем, чтобы вычислить дисперсию.Тем не менее, он выделяет еще ~ 13GB для этого.Зачем ему нужно O (N) место?Или я неправильно звоню numpy.var?

import numpy as np
# data = ...
print('Variance: ', np.var(data))

1 Ответ

0 голосов
/ 20 мая 2019

NumPy создаст промежуточный массив для вычисления abs(data - data.mean()) ** 2 для вычисления дисперсии. Вы можете написать свою собственную функцию дисперсии с циклом и сделать это быстро с Numba:

import numpy as np
import numba as nb

@nb.njit(parallel=True)
def var_nb(a, ddof=0):
    n = len(a)
    s = a.sum()
    m = s / (n - ddof)
    v = 0
    for i in nb.prange(n):
        v += abs(a[i] - m) ** 2
    return v / (n - ddof)

np.random.seed(100)
a = np.random.rand(100_000)
print(np.var(a))
# 0.08349747560941487
print(var_nb(a))
# 0.08349747560941487

%timeit np.var(a)
# 143 µs ± 414 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit var_nb(a)
# 40.2 µs ± 530 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
...