为何numpy.ndarray.view将两个np.uint8转为np.uint16结果顺序相反?
为什么用numpy.view转换uint8数组到uint16得到513而不是258?
这完全是**字节序(endianness)**在搞鬼!简单说就是你的CPU存储多字节数据时,字节的排列顺序和你预期的不一样。
先拆解一下数值:
- 你预期的258 = 1×256 + 2,对应二进制是
00000001 00000010(把第一个uint8元素1当高字节,第二个2当低字节) - 实际得到的513 = 2×256 + 1,对应二进制是
00000010 00000001(把第二个元素2当高字节,第一个1当低字节)
核心原因:你的系统是小端序(Little-Endian)
numpy的view()方法不会重新排列字节,它只是直接读取内存里的原始字节,按照指定的 dtype 解析。而绝大多数现代CPU(比如x86架构)都是小端序:
- 小端序会把低字节存在内存的低地址,高字节存在内存的高地址
- 你的数组
a = np.array([1,2], dtype=np.uint8)在内存里的存储顺序是:低地址放1,高地址放2 - 当用
view(np.uint16)解析时,小端序会把低地址的1当作uint16的低8位,高地址的2当作uint16的高8位,所以计算出来就是 2×256 + 1 = 513
怎么得到你预期的258?
有两种简单的方法:
- 指定大端序(Big-Endian)的 dtype 来view:
import numpy as np a = np.array([1, 2], dtype=np.uint8) print(a.view('>u2')) # 输出 [258],>表示大端序,u2代表uint16
大端序会把内存里先出现的字节当作高8位,后出现的当作低8位,正好符合你的预期。
- 先反转数组的字节顺序,再view:
print(a[::-1].view(np.uint16)) # 输出 [258]
把数组倒过来后,内存里的字节顺序变成2在前、1在后,小端序解析时就会得到1×256 +2=258。
内容的提问来源于stack exchange,提问作者finefoot
相关产品推荐
相关产品推荐

