numpy 中的 dtype= 和 .astype() 有什么区别?

新手上路,请多包涵

上下文:我想使用 numpy ndarraysfloat32 而不是 float64

编辑:附加上下文——我担心 numpy 是如何执行这些调用的,因为它们将作为神经网络中反向传播例程的一部分重复发生。我希望网络在 float32 中执行所有加法/减法/乘法/除法以进行验证,因为我想将结果与另一组的工作进行比较。 It seems like initialization for methods like randn will always go from float64 -> float32 with .astype() casting. Once my ndarray is of type float32 if i use np.dot for example will those multiplications happen in float32 ?我该如何验证?

我不清楚文档 - http://docs.scipy.org/doc/numpy/reference/generated/numpy.dot.html

我发现我可以将 .astype('float32') 添加到 numpy 调用的末尾,例如 np.random.randn(y, 1).astype('float32')

我还看到 dtype=np.float32 是一个选项,例如 np.zeros(5, dtype=np.float32) 。但是,尝试 np.random.randn((y, 1), dtype=np.float32) 返回以下错误:

     b = np.random.randn((3,1), dtype=np.float32)
TypeError: randn() got an unexpected keyword argument 'dtype'

将类型声明为 float32 使用 dtype 和使用 .astype() 之间有什么区别?

b = np.zeros(5, dtype=np.float32)b = np.zeros(5).astype('float32') 评估时:

 print(type(b))
print(b[0])
print(type(b[0]))

印刷:

 [ 0.  0.  0.  0.  0.]
<class 'numpy.ndarray'>
0.0
<class 'numpy.float32'>

原文由 phoenixdown 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 810
2 个回答

让我们看看我是否可以解决我在评论中看到的一些困惑。

做一个数组:

 In [609]: x=np.arange(5)
In [610]: x
Out[610]: array([0, 1, 2, 3, 4])
In [611]: x.dtype
Out[611]: dtype('int32')

arange 的默认值是生成一个 int32。

astype 是数组方法;它可以用于任何数组:

 In [612]: x.astype(np.float32)
Out[612]: array([ 0.,  1.,  2.,  3.,  4.], dtype=float32)

arange 还需要一个 dtype 参数

In [614]: np.arange(5, dtype=np.float32)
Out[614]: array([ 0.,  1.,  2.,  3.,  4.], dtype=float32)

它是先创建 int 数组并转换它,还是直接制作 float32 与我无关。这是一个基本操作,在编译代码中完成。

我也可以给它一个 float stop 值,在这种情况下它会给我一个 float 数组——默认的 float 类型。

 In [615]: np.arange(5.0)
Out[615]: array([ 0.,  1.,  2.,  3.,  4.])
In [616]: _.dtype
Out[616]: dtype('float64')

zeros 类似;默认 dtype 是 float64,但我可以通过参数更改它。由于它的主要任务是分配内存,并且不需要进行任何计算,因此我确信它会立即创建所需的数据类型,而无需进一步转换。但同样,这是编译后的代码,我不必担心它在幕后做了什么。

 In [618]: np.zeros(5)
Out[618]: array([ 0.,  0.,  0.,  0.,  0.])
In [619]: _.dtype
Out[619]: dtype('float64')
In [620]: np.zeros(5,dtype=np.float32)
Out[620]: array([ 0.,  0.,  0.,  0.,  0.], dtype=float32)

randn 涉及大量计算,显然它被编译为使用默认的 float 类型。它不需要数据类型。但由于结果是一个数组,因此可以使用 astype 进行转换。

 In [623]: np.random.randn(3)
Out[623]: array([-0.64520949,  0.21554705,  2.16722514])
In [624]: _.dtype
Out[624]: dtype('float64')
In [625]: __.astype(np.float32)
Out[625]: array([-0.64520949,  0.21554704,  2.16722512], dtype=float32)

强调一下 astype 是一个数组的方法。它获取数组的值并生成一个具有所需 dtype 的新数组。它不会对数组本身或创建该数组的函数进行追溯(或就地)操作。

astype 的效果通常(总是?)与 dtype 参数相同,但操作顺序不同。

https://stackoverflow.com/a/39625960/901925 中,我描述了一个稀疏矩阵创建器,它采用 dtype 参数,并在最后使用 astype 方法调用来实现它。

当您进行诸如 dot* 之类的计算时,它会尝试将输出数据类型与输入相匹配。在混合类型的情况下,它采用更高精度的替代方案。

 In [642]: np.arange(5,dtype=np.float32)*np.arange(5,dtype=np.float64)
Out[642]: array([  0.,   1.,   4.,   9.,  16.])
In [643]: _.dtype
Out[643]: dtype('float64')
In [644]: np.arange(5,dtype=np.float32)*np.arange(5,dtype=np.float32)
Out[644]: array([  0.,   1.,   4.,   9.,  16.], dtype=float32)

有铸造规则。查找这些的一种方法是使用 can_cast 函数:

 In [649]: np.can_cast(np.float64,np.float32)
Out[649]: False
In [650]: np.can_cast(np.float32,np.float64)
Out[650]: True

在某些计算中,它可能会将 32 转换为 64,进行计算,然后转换回 32。目的是避免舍入错误。但我不知道您是如何从文档或测试中发现这一点的。

原文由 hpaulj 发布,翻译遵循 CC BY-SA 4.0 许可协议

arr1 = np.array([25, 56, 12, 85, 34, 75])
arr2 = np.array([42, 3, 86, 32, 856, 46])

arr1.astype(np.complex)
print (arr1)
print(type(arr1[0]))
print(arr1.astype(np.complex))
arr2 = np.array(arr2,dtype='complex')
print(arr2)
print(type(arr2[0]))

以上输出

[25 56 12 85 34 75]
<class 'numpy.int64'>
[25.+0.j 56.+0.j 12.+0.j 85.+0.j 34.+0.j 75.+0.j]
[ 42.+0.j   3.+0.j  86.+0.j  32.+0.j 856.+0.j  46.+0.j]
<class 'numpy.complex128'>

可以看出 astype 像我们在普通类型转换中所做的那样暂时更改类型,但是泛型方法永久更改类型

原文由 Naresh Joshi 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进