更改 dtype 时 Numpy 数组形状会发生变化

Posted

技术标签:

【中文标题】更改 dtype 时 Numpy 数组形状会发生变化【英文标题】:Numpy Array shape changes when changing dtype 【发布时间】:2018-04-07 14:59:52 【问题描述】:

为什么改变 numpy 数组元素的 dtype 会改变数组的形状?我是 numpy 的新手,我试图将 dtype 从现有的 np.int32 更改为 np.float16。这样做会改变数组的形状,但更改为 np.float32 不会修改形状。

>>> import numpy as np
>>> arr1=np.array([1,2,3,4]
>>> arr1
array([1, 2, 3, 4])
>>> arr1.shape
(4,)
>>> arr1.dtype=np.float16
>>> arr1
array([  5.96046448e-08,   0.00000000e+00,   1.19209290e-07,
     0.00000000e+00,   1.78813934e-07,   0.00000000e+00,
     2.38418579e-07,   0.00000000e+00], dtype=float16)
>>> arr1.shape
(8,)

【问题讨论】:

【参考方案1】:

您不应该使用属性数据类型来“更改”数组的数据类型。您还可以看到,与原始数字相比,新数字没有意义。

您应该使用arr1.astype(np.float16)

我的猜测是,通过直接更改 dtype,您只需告诉 numpy 更改它为每个元素读取的内存量。因此,由于您从 float32 减少到 float16,这是内存表示的一半,因此您将获得两倍的大小。

【讨论】:

【参考方案2】:

因为更改数组的数据类型会更改实际存储的字节的含义,以及它们中有多少组成一个值。 您的初始数组可能具有数据类型int32,因此四个值中的每一个都包含四个字节:

a = np.array([1, 2, 3, 4], dtype=np.int32)
a
>>> array([1, 2, 3, 4], dtype=int32)
bytes(a)
>>> b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00'

改变数据类型并不会改变存储的字节,只是改变它们的含义:

a.dtype = np.float16
bytes(a)
>>> b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00'
a
>>> array([  5.96046448e-08,   0.00000000e+00,   1.19209290e-07,
     0.00000000e+00,   1.78813934e-07,   0.00000000e+00,
     2.38418579e-07,   0.00000000e+00], dtype=float16)

要实际转换值,请使用.astype

a.astype(np.float32)
>>> array([ 1.,  2.,  3.,  4.], dtype=float32)

【讨论】:

【参考方案3】:

如果你想改变数组的数据类型,你应该做arr1.astype(np.float16)

我对此并不完全确定,但我猜测 numpy 通过将数组的内存使用量除以数据类型的大小来计算形状。

如果你直接修改dtype,数组仍然认为它的元素大小相同,所以你可能会得到不同的答案。

【讨论】:

以上是关于更改 dtype 时 Numpy 数组形状会发生变化的主要内容,如果未能解决你的问题,请参考以下文章

NumPy数组创建例程

Numpy总结第三节:Numpy创建数组

Numpy 创建数组的常用函数

如何更改 tensorflow 的 numpy 数组的 dtypes

『Numpy』numpy.dtype内存数据解析方式指导

无法分配具有形状和数据类型的数组