首页 > 解决方案 > Numpy dtype 视图

问题描述

我正在遵循下面 lonk 中显示的教程,Dtype 视图部分:

https://scipy-cookbook.readthedocs.io/items/ViewsVsCopies.html

我在下面复制了它:

import numpy as np

b = np.arange(10, dtype='int16')
b
#array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int16)
v3 = b.view('int32')
v3 += 1
b
#array([1, 1, 3, 3, 5, 5, 7, 7, 9, 9], dtype=int16)
v4 = b.view('int8')
v4
#array([1, 0, 1, 0, 3, 0, 3, 0, 5, 0, 5, 0, 7, 0, 7, 0, 9, 0, 9, 0], dtype=int8)

我主要对为什么出现的 v3 感到困惑?

array([ 65536, 196610, 327684, 458758, 589832], dtype=int32)

尽管外观 v3 在被视为 ('int16') 时仍然等于 b,如下代码所示:

v3.view('int16')
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int16)

我也对加法表达式 v3 += 1 之后的 b 值感到有些困惑:

array([1, 1, 3, 3, 5, 5, 7, 7, 9, 9], dtype=int16)

这里 (1, dtype='int32') 被添加到 v3,而 v3 又将其添加到 b。

这种视图,dtype 表达式是否总是更新正在查看的数组,在这种情况下是 b?

由于 ('int32') dtype 是两倍大,它将具有两倍于 'int16' 值的长度,因此它一次覆盖其中两个,它的步幅也将是两倍大,因此它会拾取每个b中的第二个数字。

这种解释正确吗?

为什么每个数字都返回两次,而不是只返回一个截断的 b?

array([1, 3, 5, 7, 9], dtype=int16)

标签: python-3.xnumpy

解决方案


这与数组的存储方式有关。按照连续(重要!)的顺序,实际的内存块b看起来像

[0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0...]

其中每个数字代表byte内存中的一个。一块内存可以被视为任何dtype. 看成 时int16,两个bytes 组成一个数,结果变成

[00 10 20 30 40 50 60 70...]

当被视为 时int32,四个bytes 组成一个数字,结果变为

[0010 2030 4050...]

现代 PC 使用little-endian存储数字。这意味着 egint32(1234)应该被解释为1*256^0 + 2*256^1 + 3*256^2 + 4*256^3whileint16(56)应该被解释为5*256^0 + 6*256^1。出于这个原因,0010成为655362030成为196610,等等。

向视图添加一个时int32,由于int32视图在技术上与int16数组共享相同的内存块(视图总是与查看的数组共享内存块),因此int16数组也会被修改。加int32一表示加法1000(即在 中最左边的数加一xxxx),对应256^0于每个偶数位置号中的项:

int32 view: [1010 3030 5050 7070]
int16 view: [10 10 30 30 50 50 70 70]

因此,int16 视图转换为[1 1 3 3 5 5 7 7...].

顺便提一句:

  • 文字1没有dtype. 当 numpy 无法确定更好的类型时,它可能会被键入long(即)。但是当做类似的int32事情时a += 1,数字将被输入dtypea

  • Numpy 支持big-endian数组(即int32(1234)上面变成4321了内存)。在这种情况下,修改视图的结果将完全不同

  • Numpy 还支持实际存储在相反方向的数组(即[int16(10), int16(20), int16(30), int16(40)]实际上[4 0 3 0 2 0 1 0]在内存中)。这也会产生影响

  • 整数在最后一个字节的第一位有一个符号位。这意味着如果整数为负数,结果将远远超出您的预期。

您认为“查看”不同dtype不应以随机方式更改值的想法是指casting (即astype)。强制转换返回具有相同值但不同的新副本dtype。由于 的大小差异dtype,强制转换无法与原始数组共享内存,并且或多或少是低效的。


推荐阅读