NumPy基础知识(六)

NumPy基础知识(六)

字节交换

字节顺序和ndarrays简介

ndarray是一个对象,在存储器提供一个python阵列接口到数据。

通常,您要使用数组查看的内存与运行Python的计算机的字节顺序不同。

例如,我可能正在使用低端CPU的计算机(例如Intel Pentium),但是我已经从由大端计算机编写的文件中加载了一些数据。假设我已经从Sun(big-endian)计算机编写的文件中加载了4个字节。我知道这4个字节代表两个16位整数。在big-endian计算机上,先存储两个字节的整数,然后再存储最高有效字节(MSB),然后存储最低有效字节(LSB)。因此,字节按内存顺序为:

  1. MSB整数1

  2. LSB整数1

  3. MSB整数2

  4. 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')

我们可能要使用anndarray来访问这些整数。在这种情况下,我们可以在该内存周围创建一个数组,并告诉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。的>意思是“大端”(<是小端)和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设置为match(dtype也是big-endian)。但是,有时您需要将它们翻转。

警告

标量目前不包含字节顺序信息,因此从数组中提取标量将返回原始字节顺序的整数。因此:

>>>
>>> big_end_arr[0].dtype.byteorder == little_end_u4[0].dtype.byteorder
True

更改字节顺序

从介绍中可以想象,有两种方法可以影响数组的字节顺序与其所关注的基础内存之间的关系:

  • 更改数组dtype中的字节顺序信息,以使其将基础数据解释为不同的字节顺序。这是角色arr.newbyteorder()

  • 更改基础数据的字节顺序,保持dtype解释不变。这是做什么的arr.byteswap()

需要更改字节顺序的常见情况是:

  1. 您的数据和dtype的字节序不匹配,并且您想更改dtype使其与数据匹配。

  2. 您的数据和dtype的字节序不匹配,并且您想交换数据,使其与dtype匹配

  3. 您的数据和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

数据和类型字节顺序不匹配,变化数据,以匹配D型

如果您需要对内存中的数据进行某种排序,则可能需要这样做。例如,您可能正在将内存写出到需要特定字节顺序的文件中。

>>>
>>> fixed_end_mem_arr = wrong_end_dtype_arr.byteswap()
>>> fixed_end_mem_arr[0]
1

现在,数组在内存更改:

>>>
>>> fixed_end_mem_arr.tobytes() == big_end_buffer
False

数据和D型字节顺序匹配,交换数据和D型

您可能具有正确指定的数组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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kimboyang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值