我认为这是一项简单的任务,但我遇到了麻烦。
我有一个函数,它接受数组中的索引并返回属于该索引的值。我想,有效地将值写入一个numpy数组。
我找到numpy.fromfunction
,但它的行为并不像documentation建议的那样。它似乎“向量化”了这个函数,这意味着它不是传递实际的索引而是传递了一个庞大的索引数组:
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
(如果我们使用调试器来检查i
,则它是numpy.array
实例。)
所以,如果我们尝试使用numpy的矢量化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
我们的振荡器会出现不连续性,因为numpy正在使用int16_t
来表示索引!
这里的要点与sin
无关:我希望能够编写像这样的任意python函数(是否存在numpy矢量化版本)并且能够在紧密的C中运行它们循环(而不是一个环形的python),而不必担心整数环绕。
我是否真的必须编写自己的cython扩展才能做到这一点? numpy
是否支持在数组中每个项目运行一次python函数,并且可以访问索引?
它不一定是一个创建函数:我可以使用numpy.empty
(或者实际上,重用其他地方的现有数组。)因此,矢量化转换函数也可以。
答案 0 :(得分:0)
我认为整数环绕的问题与numpy的矢量化sin
实现无关,甚至与python或C的使用无关。
如果使用2字节有符号整数并尝试生成从0到32767之间的整数值数组,则会出现环绕错误。该数组将如下所示:
[0, 1, 2, ... , 32767, -32768, -32767, ...]
最简单的解决方案,假设内存不是太紧,就是为fromfunction
生成的整数数组使用更多字节,这样你就不会出现环绕问题(直到几十亿):
numpy.fromfunction(vsin, (len,), dtype=numpy.int32)
numpy
经过优化,可以通过在矢量化函数之间传递整个数组来快速处理数组。我认为通常numpy
工具不便于尝试每个数组元素运行一次标量函数。