Разница между векторизацией NumPy и ее автоматической векторизацией - PullRequest
0 голосов
/ 10 января 2019

Я хочу сделать много случайных прогулок и подготовить их. Функция, которая переходит из начального состояния istate в следующее состояние, просто iter = lambda istate: istate + np.random.uniform(-0.5, 0.5).

Итак, учитывая массив NumPy 'arr' со значениями каждого обхода, если я просто вызываю iter(arr), функция iter векторизована, но выполняет одинаковый бросок броска для всех элементов. Если я вместо этого вызову np.vectorize(iter)(arr), функция выполняет отдельный бросок кубика для каждого элемента.

В чем разница между двумя векторизациями? влияет ли это на производительность при использовании других видов функций?

Ответы [ 2 ]

0 голосов
/ 10 января 2019

np.vectorize для функций, которые не принимают ndarray в качестве аргумента, и это примерно цикл for, поэтому никогда не эффективен. например:

a=np.arange(1e4,dtype=float)
float.hex(a)
Traceback (most recent call last):

  File "<ipython-input-27-e5cdcd882026>", line 1, in <module>
    float.hex(a)

TypeError: descriptor 'hex' requires a 'float' object but received a 'numpy.ndarray'

np.vectorize разрешает эту операцию:

%timeit np.vectorize(float.hex)(a)
14.6 ms ± 850 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

приблизительно эквивалентно (по результату и производительности):

%timeit [float.hex(z) for z in a]
14.2 ms ± 666 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Но здесь ваш iter (переименован my_iter) принимает ndarrays:

def my_iter(x): return x+np.random.uniform(-.5,.5)

%timeit my_iter(a)
16.1 µs ± 1.1 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

В этом случае гораздо лучше, чем:

%timeit np.vectorize(my_iter)(a)
28.6 ms ± 6.49 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
0 голосов
/ 10 января 2019

Векторизованные операции NumPy , , т. Е. , np.vectorize(iter)(array) можно использовать для больших кусков посещаемых элементов. Эта функция векторизации предоставляется в первую очередь для удобства, а не для производительности. Реализация по сути является циклом for. С другой стороны, по умолчанию , iter(array) обрабатывает входной массив как объект чтения. Он используется для получения итератора над данным объектом. Если итератор определен так, чтобы возвращать новый объект, он сделает так, чтобы он мог выполнять итерацию столько раз, сколько хотел.

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