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

时间:2016-09-21 17:54:33

标签: python-3.x numpy

背景信息:我希望numpy ndarraysfloat32代替float64

编辑:附加上下文 - 我关心numpy如何执行这些调用,因为它们将作为神经网络中反向传播例程的一部分重复发生。我希望网络在float32中执行所有加法/减法/乘法/除法以进行验证,因为我想将结果与另一个组的工作进行比较。像randn这样的方法的初始化似乎总是来自float64 - > float32投标.astype()。我的ndarray类型为float32时,如果我使用np.dot,那么这些乘法会在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'>

3 个答案:

答案 0 :(得分:6)

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

制作一个数组:

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不是我所关心的。这是一个基本操作,在编译代码中完成。

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

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

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

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类型。它不需要dtype。但由于结果是数组,因此可以使用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*等计算时,会尝试将输出dtype与输入匹配。在混合类型的情况下,它具有更高精度的替代方案。

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.目的是避免舍入误差。但我不知道你是如何从文档或测试中找到的。

答案 1 :(得分:2)

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'>

可以看出,与普通类型转换一样,类型会暂时改变类型,而泛型方法会永久改变类型

答案 2 :(得分:0)

>>> a = np.ones(3, dtype=float) >>> a array([ 1., 1., 1.]) >>> b = a.astype(int) >>> b array([1, 1, 1]) >>> np.may_share_memory(a, b) False 复制数据。

astype()

请注意,即使dtype实际上相同,>>> c = a.astype(float) >>> np.may_share_memory(a, c) False 也会复制数据:

#include <iostream>    
#include <cstdlib> // for rand() and srand()
#include <ctime>
using namespace 
int main()
{
   //cout << "How many players?" << endl;
    int numplayers=1;
   //cin >> numplayers;

    int players[numplayers];
    int x=0,y=0;
    srand(time(0));
    x=(rand() % 6 + 1);
    y=(rand() % 6 + 1);
    players[1]=players[1]+x+y;
    cout << ("Your score is" + players[1]) << endl;
    cin >> numplayers;       
}