python-3.x - 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)
解决方案
这与数组的存储方式有关。按照连续(重要!)的顺序,实际的内存块b
看起来像
[0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0...]
其中每个数字代表byte
内存中的一个。一块内存可以被视为任何dtype
. 看成 时int16
,两个byte
s 组成一个数,结果变成
[00 10 20 30 40 50 60 70...]
当被视为 时int32
,四个byte
s 组成一个数字,结果变为
[0010 2030 4050...]
现代 PC 使用little-endian存储数字。这意味着 egint32(1234)
应该被解释为1*256^0 + 2*256^1 + 3*256^2 + 4*256^3
whileint16(56)
应该被解释为5*256^0 + 6*256^1
。出于这个原因,0010
成为65536
,2030
成为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
,数字将被输入dtype
a
Numpy 支持big-endian数组(即
int32(1234)
上面变成4321
了内存)。在这种情况下,修改视图的结果将完全不同Numpy 还支持实际存储在相反方向的数组(即
[int16(10), int16(20), int16(30), int16(40)]
实际上[4 0 3 0 2 0 1 0]
在内存中)。这也会产生影响整数在最后一个字节的第一位有一个符号位。这意味着如果整数为负数,结果将远远超出您的预期。
您认为“查看”不同dtype
不应以随机方式更改值的想法是指cast
ing (即astype
)。强制转换返回具有相同值但不同的新副本dtype
。由于 的大小差异dtype
,强制转换无法与原始数组共享内存,并且或多或少是低效的。
推荐阅读
- node.js - 用于不同实验室环境的 Mongoose 模型架构设置
- python - 我不明白使用 mxnet 的“形状不一致”错误
- mysql - 安装期间 phpmyadmin 错误 1064 (42000)
- c++ - 你如何在 C++ 中执行“while(choice not in operation)”
- java - JAVAFX CheckBox 线程
- css - 媒体查询和 vuejs
- c - `"apue.h"`不是全局环境 PATH ,但程序可以检索它
- node.js - 支付成功后如何跳转到外部网页?
- python-2.7 - 如何选择两个不同列的随机日期时间?
- c++ - 如何使用两个不同的参数值调用我的模拟方法两次