从python函数生成一个numpy数组

时间:2015-05-30 14:08:09

标签: python arrays numpy

我认为这是一项简单的任务,但我遇到了麻烦。

我有一个函数,它接受数组中的索引并返回属于该索引的值。我想,有效地将值写入一个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(或者实际上,重用其他地方的现有数组。)因此,矢量化转换函数也可以。

1 个答案:

答案 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工具不便于尝试每个数组元素运行一次标量函数。