Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Numpy标量上的二进制操作会自动向上转换为float64_Python_Numpy_Numba_Single Precision - Fatal编程技术网

Python Numpy标量上的二进制操作会自动向上转换为float64

Python Numpy标量上的二进制操作会自动向上转换为float64,python,numpy,numba,single-precision,Python,Numpy,Numba,Single Precision,我想在np.float32和内置Python int和float之间执行二进制操作(如加法和乘法),并得到一个np.float32作为返回类型。但是,它会自动升级为np.64 示例代码: >>> a = np.float32(5) >>> a.dtype dtype('float32') >>> b = a + 2 >>> b.dtype dtype('float64') 如果我用一个np.float128这样做,b也会变

我想在np.float32和内置Python int和float之间执行二进制操作(如加法和乘法),并得到一个np.float32作为返回类型。但是,它会自动升级为np.64

示例代码:

>>> a = np.float32(5)
>>> a.dtype
dtype('float32')
>>> b = a + 2
>>> b.dtype
dtype('float64')
如果我用一个np.float128这样做,b也会变成一个np.float128。这是好的,因为这样可以保持精度。然而,在我的示例中,不需要向上转换到np.float64来保持精度,但它仍然存在。如果我将2.0(一个Python浮点(64位))添加到a而不是2,那么转换将是有意义的。但即使在这里,我也不想要它

因此,我的问题是:在将二进制运算符应用于np.float32和内置Python int/float时,如何更改转换?或者,将单精度作为所有计算的标准,而不是双精度,也可以算作解决方案,因为我从来都不需要双精度。其他人要求这样做,但似乎没有找到解决办法

我知道numpy数组和数据类型。这里我得到了想要的行为,因为数组总是保留其数据类型。然而,当我对数组的单个元素执行操作时,我得到了不需要的行为。 我对一个解决方案有一个模糊的想法,涉及到子类化np.ndarray(或np.float32)和更改uu数组u优先级uu的值。到目前为止,我还不能让它工作


我为什么在乎?我正在尝试使用Numba编写一个n体代码。这就是为什么我不能简单地对整个阵列执行操作的原因。将所有np.float64更改为np.float32会使速度提高约2倍,这一点很重要。np.float64-casting行为会彻底破坏这种速度,因为我的np.float32数组上的所有操作都是以64精度完成的,然后向下转换到32精度。

我不确定NumPy行为,或者你到底是如何尝试使用Numba的,但是明确说明Numba类型可能会有所帮助。例如,如果您这样做:

@jit
def foo(a):
    return a[0] + 2;

a = np.array([3.3], dtype='f4')
foo(a)
@jit
def foo():
    a = np.arange(1000000, dtype='f4')
    result = np.zeros(1000000, dtype='f4')
    for i in range(a.size):
        result[0] = a[0] + 2
[0]中的float32值在add操作之前被提升为float64(如果您不介意深入研究llvm IR,您可以通过使用numba命令运行代码并使用--dump llvm或--dump optimized标志:numba--dump optimized numba_test.py来亲自看到这一点)。但是,通过将函数签名(包括返回类型)指定为float32:

@jit('f4(f4[:]'))
def foo(a):
    return a[0] + 2;
[0]中的值不会提升为float64,尽管结果被强制转换为float64,以便在函数返回Python land时将其转换为Python float对象

如果可以事先分配一个数组来保存结果,则可以执行以下操作:

@jit
def foo(a):
    return a[0] + 2;

a = np.array([3.3], dtype='f4')
foo(a)
@jit
def foo():
    a = np.arange(1000000, dtype='f4')
    result = np.zeros(1000000, dtype='f4')
    for i in range(a.size):
        result[0] = a[0] + 2
即使您自己进行循环,编译代码的性能也应该与NumPy ufunc相当,并且不应该发生对float64的强制转换(同样,这可以通过查看Numba生成的llvm IR来验证)