Использование `numpy.vectorize` для создания многомерного массива приводит к ValueError: установка элемента массива с последовательностью - PullRequest
0 голосов
/ 22 мая 2018

Эта проблема возникает только тогда, когда моя функция dummy возвращает массив, и, таким образом, создается многомерный массив.

Я сократил проблему до следующего примера:

def dummy(x):
    y = np.array([np.sin(x), np.cos(x)])
    return y

x = np.array([0, np.pi/2, np.pi])

Код, который я хочу оптимизировать, выглядит следующим образом:

y = []
for x_i in x:
    y_i = dummy(x_i)
    y.append(y_i)
y = np.array(y)

Поэтому я подумал, что мог бы использовать vectorize, чтобы избавиться от медленного цикла:

y = np.vectorize(dummy)(x)

Но этоприводит к

ValueError: setting an array element with a sequence.

Где четная последовательность, о которой говорит ошибка?!

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Ваша функция возвращает массив при наличии скаляра:

In [233]: def dummy(x):
     ...:     y = np.array([np.sin(x), np.cos(x)])
     ...:     return y
     ...: 
     ...: 
In [234]: dummy(1)
Out[234]: array([0.84147098, 0.54030231])



In [235]: f = np.vectorize(dummy)
In [236]: f([0,1,2])
...
ValueError: setting an array element with a sequence.

vectorize создает пустой массив результатов и пытается поместить в него результат каждого вычисления.Но ячейка целевого массива не может принять массив.

Если мы указываем параметр otypes, он работает:

In [237]: f = np.vectorize(dummy, otypes=[object])
In [238]: f([0,1,2])
Out[238]: 
array([array([0., 1.]), array([0.84147098, 0.54030231]),
       array([ 0.90929743, -0.41614684])], dtype=object)

То есть каждый массив dummy помещаетсяв элементе shape (3,) результирующего массива.

Поскольку массивы компонентов имеют одинаковую форму, мы можем stack их:

In [239]: np.stack(_)
Out[239]: 
array([[ 0.        ,  1.        ],
       [ 0.84147098,  0.54030231],
       [ 0.90929743, -0.41614684]])

Но, как отмечалось, vectorize не обещает ускорения.Я подозреваю, что мы могли бы также использовать более новый параметр signature, но это еще медленнее.

vectorize имеет некоторый смысл, если ваша функция принимает несколько скалярных аргументов, и вы хотели бы использовать преимущества широковещательной трансляции, когдакормление наборов ценностей.Но как замена простой итерации над 1d-массивом, это не улучшение.

0 голосов
/ 22 мая 2018

Я тоже не совсем понимаю ошибку, но в python 3.6.3 вы можете просто написать:

y = dummy(x)

, чтобы она автоматически векторизовалась.

Также в официальном документация там написано следующее:

Функция векторизации предоставляется в первую очередь для удобства, а не для производительности.Реализация по сути является циклом for.

Надеюсь, это хоть немного помогло.

...