Python / Numpy - маскированные массивы очень медленные - PullRequest
18 голосов
/ 23 апреля 2011

Есть ли что-нибудь, что я могу сделать, чтобы ускорить маскированные массивы в numpy?У меня была ужасно неэффективная функция, которую я переписал для использования замаскированных массивов (где я мог просто маскировать строки вместо того, чтобы делать копии и удалять строки, как я делал).Однако я был шокирован, обнаружив, что замаскированная функция была в 10 раз медленнее, потому что замаскированные массивы намного медленнее.

В качестве примера возьмем следующее (замаскированное для меня более чем в 6 раз медленнее):

import timeit
import numpy as np
import numpy.ma as ma

def test(row):
   return row[0] + row[1]

a = np.arange(1000).reshape(500, 2)
t = timeit.Timer('np.apply_along_axis(test, 1, a)','from __main__ import test, a, np')
print round(t.timeit(100), 6)

b = ma.array(a)
t = timeit.Timer('ma.apply_along_axis(test, 1, b)','from __main__ import test, b, ma')
print round(t.timeit(100), 6)

Ответы [ 2 ]

4 голосов
/ 05 июля 2011

Я понятия не имею, почему функции массива в масках движутся так медленно, но, поскольку кажется, что вы используете маску для выбора строк (в отличие от отдельных значений), вы можете создать регулярный массив из строк в маске и использовать вместо этого функция np:

b.mask = np.zeros(500)
b.mask[498] = True
t = timeit.Timer('c=b.view(np.ndarray)[~b.mask[:,0]]; np.apply_along_axis(test, 1, c)','from __main__ import test, b, ma, np')
print round(t.timeit(100), 6)

Еще лучше, вообще не использовать маскированные массивы; просто сохраните ваши данные и массив 1D-маски в виде отдельных переменных:

a = np.arange(1000).reshape(500, 2)
mask = np.ones(a.shape[0], dtype=bool)
mask[498] = False
out = np.apply_along_axis(test, 1, a[mask])
0 голосов
/ 23 апреля 2011

РЕДАКТИРОВАТЬ: я проверял это неправильно, используя np.apply_along_axis вместо np.ma.apply_along_axis, извините.Поэтому я подтверждаю, что версия маскированного массива более чем в 5 раз медленнее и в Linux / numpy 1.5.1

In [16]: %timeit np.apply_along_axis(test, 1, a)
100 loops, best of 3: 15.3 ms per loop

In [17]: %timeit np.apply_along_axis(test, 1, b)
100 loops, best of 3: 15.3 ms per loop

In [12]: %timeit np.ma.apply_along_axis(test, 1, b)
10 loops, best of 3: 80.8 ms per loop

In [18]: np.__version__
Out[18]: '1.5.1'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...