У меня есть то, что, как я думал, будет простой задачей в numpy, но у меня проблемы.Создайте массив numpy из функции python
У меня есть функция, которая принимает индекс в массиве и возвращает значение, которое принадлежит этому индексу. Я хотел бы, эффективно, записать значения в массив numpy.
Я нашел numpy.fromfunction
, но он не ведет себя дистанционно, как предлагает documentation. Это, кажется, «vectorise» функция, которая означает, что вместо передачи фактических индексов она проходит Numpy массив индексов: (. Если мы будем использовать отладчик для проверки i
, это numpy.array
экземпляр)
def vsin(i):
return float(round(A * math.sin((2 * pi * wf) * i)))
numpy.fromfunction(vsin, (len,), dtype=numpy.int16)
# TypeError: only length-1 arrays can be converted to Python scalars
Таким образом, если мы будем пытаться использовать NumPy-х vectorised sin
функции:
def vsin(i):
return (A * numpy.sin((2 * pi * wf) * i)).astype(numpy.int16)
numpy.fromfunction(vsin, (len,), dtype=numpy.int16)
мы не получаем ошибку типа, но если len > 2**15
мы получаем разрывы разделочной accross нашего осциллятора, потому что numpy использует int16_t
для представления индекса!
В частности, речь идет не о sin
: Я хочу иметь возможность писать произвольные функции python, подобные этому (независимо от того, существует ли версия с числовым вектором или нет) и иметь возможность запускать их внутри жесткой петли C (скорее чем окольный питон один), и не нужно беспокоиться о целочисленном wraparound.
Должен ли я писать собственное расширение для cython, чтобы иметь возможность сделать это? У numpy
есть поддержка для запуска функций python один раз за элемент в массиве с доступом к индексу?
Это не должно быть функцией создания: я могу использовать numpy.empty
(или, действительно, повторно использовать существующий массив из другого места.) Таким образом, также была бы реализована векторная функция преобразования.
FYI, на данный момент я просто запускаю цикл python, который не слишком медленен для небольших массивов, с которыми я имею дело первоначально. – tehwalrus
Почему вы не используете что-то вроде 'vsin (np.arange (1000))' или 'vsin (np.linspace (0,4,100)'? Посмотрите на код 'fromfunction'. Все, что он делает, это' vsin (np. индексы ({len,)) '. Если' индексы' не дают правильных значений 'i', не используйте их. – hpaulj