Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.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类型转换?_Python_Numpy_Tensorflow_Floating Point - Fatal编程技术网

Python 如何避免Numpy类型转换?

Python 如何避免Numpy类型转换?,python,numpy,tensorflow,floating-point,Python,Numpy,Tensorflow,Floating Point,是否可以避免或发出从整数和32位浮点数组到64位浮点数组的自动Numpy类型转换警告 我的使用案例是,我正在开发一个大型分析包(20k行Python和Numpy),目前混合了float 32和64以及一些int数据类型,很可能会导致次优性能和内存浪费,基本上我希望在任何地方都一致地使用float 32 我知道,在Tensorflow中,将两个不同数据类型的数组组合在一起会产生错误,这正是因为隐式转换到float64会导致性能不佳,并且对所有计算的张量都具有“传染性”,如果隐式转换,则很难找到引入

是否可以避免或发出从整数和
32位浮点数组到
64位浮点数组的自动Numpy类型转换警告

我的使用案例是,我正在开发一个大型分析包(20k行Python和Numpy),目前混合了float 32和64以及一些int数据类型,很可能会导致次优性能和内存浪费,基本上我希望在任何地方都一致地使用float 32

我知道,在Tensorflow中,将两个不同数据类型的数组组合在一起会产生错误,这正是因为隐式转换到float64会导致性能不佳,并且对所有计算的张量都具有“传染性”,如果隐式转换,则很难找到引入的位置


在Numpy中寻找一个选项,或者寻找一种monkey patch Numpy的方法,使其在这方面的行为类似于Tensorflow,即在诸如
np.add
np.mul
等操作的隐式类型转换上发出错误,或者更好,会发出带有打印回溯的警告,以便继续执行,但我知道发生了什么。可能吗?

免责声明:我没有以任何严肃的方式对此进行测试,但这似乎是一条有希望的途径

操纵ufunc行为的一种相对轻松的方式似乎是:使用和重写
\uuuuuuunc\uuuuu
。例如,如果您满足于捕获任何产生
float64

class no64(np.ndarray):
    def __array_ufunc__(self, ufunc, method, *inputs, **kwds):
        ret = getattr(ufunc, method)(*map(np.asarray,inputs), **kwds)
        # some ufuncs return multiple arrays:
        if isinstance(ret,tuple):
            if any(x.dtype == np.float64 for x in ret):
                raise ValueError
            return (*(x.view(no64) for x in ret),)
        if ret.dtype == np.float64:
             raise ValueError
        return ret.view(no64)

x = np.arange(6,dtype=np.float32).view(no64)
现在让我们看看我们班能做些什么:

x*x
# no64([ 0.,  1.,  4.,  9., 16., 25.], dtype=float32)
np.sin(x)
# no64([ 0.        ,  0.84147096,  0.9092974 ,  0.14112   , -0.7568025 ,
#       -0.9589243 ], dtype=float32)
np.frexp(x)
# (no64([0.   , 0.5  , 0.5  , 0.75 , 0.5  , 0.625], dtype=float32), no64([0, 1, 2, 2, 3, 3], dtype=int32))
现在让我们将其与64位参数配对:

x + np.arange(6)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#   File "<stdin>", line 9, in __array_ufunc__
# ValueError

np.multiply.outer(x, np.arange(2.0))
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#   File "<stdin>", line 9, in __array_ufunc__
# ValueError

\uuuu数组\函数\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。看起来默认值是
same\u kind'https://docs.scipy.org/doc/numpy/reference/ufuncs.html#casting-规则,https://docs.scipy.org/doc/numpy/reference/generated/numpy.can_cast.html#numpy.can_cast.  我想您需要
casting='no'`。它也可能有助于提供
out
参数。但是在测试中,
np.multiply(x,2.,casting='no')
给了我一个错误,因为它无法将
np.array(2.)
(float64)强制转换为float32(以匹配
x
。因此此转换参数可能与生成的
dtype
关系不大,而与作为输入的内容关系更大。
np.outer(x, np.arange(2.0))  # not a ufunc, so slips through
# array([[0., 0.],
#        [0., 1.],
#        [0., 2.],
#        [0., 3.],
#        [0., 4.],
#        [0., 5.]])