等待下一个秋

  • Spark
  • Flink
  • Hive
  • 数据仓库
  • ClickHouse
  • 收徒弟
  • Java
    • Spring
    • Mybatis
    • SpringBoot
    • 面试题
  • Python
    • Python基础
    • 爬虫
    • Numpy
    • matplotlib
    • Flask
  • 技术杂谈
    • Linux知识
    • Docker
    • Git教程
    • Redis教程
    • mysql
    • 前端
    • R语言
    • 机器学习
  • 关于我
  • 其它
    • 副业挣钱
    • 资料下载
    • 资料文档
专注于Hadoop/Spark/Flink/Hive/数据仓库等
关注公众号:大数据技术派,获取更多学习资料。
  1. 首页
  2. Python
  3. Numpy
  4. 正文

NumPy字节交换

2020年11月10日 907点热度 0人点赞 0条评论

字节排序和ndarrays简介

ndarray是一个为内存中的数据提供python数组接口的对象。

经常发生的情况是,要用数组查看的内存与运行Python的计算机的字节顺序不同。

例如,我可能正在使用带有 little-endian CPU 的计算机 - 例如Intel Pentium,但是我已经从一个由 big-endian计算机 编写的文件中加载了一些数据。假设我已经从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')

我们可能需要使用 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()。

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

  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

# 数据和类型字节顺序不匹配,更改数据以匹配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
标签: Python
最后更新:2022年7月19日

等待下一个秋

待我代码写成,便娶你为妻!专注于Hadoop/Spark/Flink/Hive/数据仓库等,关注公众号:大数据技术派,获取更多学习资料。

打赏 点赞
< 上一篇
下一篇 >

等待下一个秋

待我代码写成,便娶你为妻!专注于Hadoop/Spark/Flink/Hive/数据仓库等,关注公众号:大数据技术派,获取更多学习资料。

搜一搜
微信
最新 热点 随机
最新 热点 随机
ChatGPT可以做什么 ClickHouse 自定义分区键 ClickHouse数据副本引擎 ClickHouse ReplacingMergeTree引擎 ClickHouse MergeTree引擎 clickhouse简介
Kafka面试题总结(二) redis 删除大key集合的方法 R语言常用语法 第07讲:Flink 常见核心概念分析 前端跨域传递Cookie设置 第八章-Python3中Web开发框架flask实现粉丝关注与取消关注功能
标签聚合
大数据 数据仓库 算法 挣钱 书籍 Java Python R语言 Hive mysql Redis Flink
文章归档
  • 2023年2月
  • 2022年12月
  • 2022年11月
  • 2022年9月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年5月
  • 2020年4月
  • 2020年1月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年1月
  • 2018年12月
  • 2017年5月

©2022 ikeguang.com. 保留所有权利。

鄂ICP备2020019097号-1

鄂公网安备 42032202000160号