概述
文章
- 基础篇
- 进阶篇
- 其他篇
用户指南
NumPy 参考手册
- 数组对象
- 常量
- 通函数(ufunc)
- 常用 API
- 创建数组
- 数组处理程序
- 二进制运算
- 字符串操作
- C-Types 外部函数接口(numpy.ctypeslib)
- 时间日期相关
- 数据类型相关
- 可选的 Scipy 加速支持(numpy.dual)
- 具有自动域的数学函数( numpy.emath)
- 浮点错误处理
- 离散傅立叶变换(numpy.fft)
- 财金相关
- 实用的功能
- 特殊的 NumPy 帮助功能
- 索引相关
- 输入和输出
- 线性代数(numpy.linalg)
- 逻辑函数
- 操作掩码数组
- 数学函数(Mathematical functions)
- 矩阵库 (numpy.matlib)
- 杂项(Miscellaneous routines)
- 填充数组(Padding Arrays)
- 多项式(Polynomials)
- 随机抽样 (numpy.random)
- 操作集合(Set routines)
- 排序,搜索和计数(Sorting, searching, and counting)
- Statistics
- Test Support (numpy.testing)
- Window functions
- 打包(numpy.distutils)
- NumPy Distutils 用户指南
- NumPy C-API
- NumPy 的内部
- NumPy 和 SWIG
其他文档
字节交换
字节排序和ndarrays简介
ndarray
是一个为内存中的数据提供python数组接口的对象。
经常发生的情况是,要用数组查看的内存与运行Python的计算机的字节顺序不同。
例如,我可能正在使用带有 little-endian CPU 的计算机 - 例如Intel Pentium,但是我已经从一个由 big-endian计算机 编写的文件中加载了一些数据。假设我已经从Sun(big-endian)计算机写入的文件中加载了4个字节。我知道这4个字节代表两个16位整数。在 big-endian 机器上,首先以最高有效字节(MSB)存储双字节整数,然后存储最低有效字节(LSB)。因此字节按内存顺序排列:
- MSB整数1
- LSB整数1
- MSB整数2
- LSB整数2
假设两个整数实际上是1和770.因为770 = 256 * 3 + 2,内存中的4个字节将分别包含:0,1,3,2。我从文件加载的字节将包含这些内容:
>>> big_end_buffer = bytearray([0,1,3,2])
>>> big_end_buffer
bytearray(b'\x00\x01\x03\x02')
我们可能需要使用 ndarray
来访问这些整数。在这种情况下,我们可以围绕这个内存创建一个数组,并告诉numpy有两个整数,并且它们是16位和Big-endian:
>>> import numpy as np
>>> big_end_arr = np.ndarray(shape=(2,),dtype='>i2', buffer=big_end_buffer)
>>> big_end_arr[0]
1
>>> big_end_arr[1]
770
注意上面的数组dtype > i2
。>
表示 big-endian
( <
是 Little-endian
),i2
表示‘有符号的2字节整数’。例如,如果我们的数据表示单个无符号4字节小端整数,则dtype字符串将为 <u4
。
事实上,为什么我们不尝试呢?
>>> little_end_u4 = np.ndarray(shape=(1,),dtype='<u4', buffer=big_end_buffer)
>>> little_end_u4[0] == 1 * 256**1 + 3 * 256**2 + 2 * 256**3
True
回到我们的 big_end_arr
- 在这种情况下我们的基础数据是big-endian(数据字节序),我们设置dtype匹配(dtype也是big-endian)。但是,有时你需要翻转它们。
警告
标量当前不包含字节顺序信息,因此从数组中提取标量将返回本机字节顺序的整数。因此:
>>> big_end_arr[0].dtype.byteorder == little_end_u4[0].dtype.byteorder
True
更改字节顺序
从介绍中可以想象,有两种方法可以影响数组的字节顺序与它所查看的底层内存之间的关系:
- 更改数组dtype中的字节顺序信息,以便将基础数据解释为不同的字节顺序。这是作用
arr.newbyteorder()
- 更改基础数据的字节顺序,保留dtype解释。这是做什么的
arr.byteswap()
。
您需要更改字节顺序的常见情况是:
- 您的数据和dtype字节顺序不匹配,并且您希望更改dtype以使其与数据匹配。
- 您的数据和dtype字节顺序不匹配,并且您希望交换数据以使它们与dtype匹配
- 您的数据和dtype字节顺序匹配,但您希望交换数据和dtype来反映这一点
数据和dtype字节顺序不匹配,更改dtype以匹配数据
我们制作一些他们不匹配的东西:
>>> wrong_end_dtype_arr = np.ndarray(shape=(2,),dtype='<i2', buffer=big_end_buffer)
>>> wrong_end_dtype_arr[0]
256
这种情况的明显解决方法是更改dtype,以便它给出正确的字节顺序:
>>> fixed_end_dtype_arr = wrong_end_dtype_arr.newbyteorder()
>>> fixed_end_dtype_arr[0]
1
请注意,内存中的数组未更改:
>>> fixed_end_dtype_arr.tobytes() == big_end_buffer
True
数据和类型字节顺序不匹配,更改数据以匹配dtype
如果您需要内存中的数据是某种顺序,您可能希望这样做。例如,您可能正在将内存写入需要特定字节排序的文件。
>>> fixed_end_mem_arr = wrong_end_dtype_arr.byteswap()
>>> fixed_end_mem_arr[0]
1
现在数组 已 在内存中更改:
>>> fixed_end_mem_arr.tobytes() == big_end_buffer
False
数据和dtype字节序匹配,交换数据和dtype
您可能有一个正确指定的数组dtype,但是您需要数组在内存中具有相反的字节顺序,并且您希望dtype匹配以便数组值有意义。在这种情况下,您只需执行上述两个操作:
>>> swapped_end_arr = big_end_arr.byteswap().newbyteorder()
>>> swapped_end_arr[0]
1
>>> swapped_end_arr.tobytes() == big_end_buffer
False
使用ndarray astype方法可以更简单地将数据转换为特定的dtype和字节顺序:
>>> swapped_end_arr = big_end_arr.astype('<i2')
>>> swapped_end_arr[0]
1
>>> swapped_end_arr.tobytes() == big_end_buffer
False
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论