首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >人工智能之数据分析 numpy:第十一章 字符串与字节交换

人工智能之数据分析 numpy:第十一章 字符串与字节交换

原创
作者头像
咚咚王
发布2025-11-23 19:16:01
发布2025-11-23 19:16:01
280
举报

人工智能之数据分析 numpy

第十一章 字符串与字节交换


前言

在 NumPy 中,字符串数组字节序(Endianness)交换 是两个重要但常被忽视的主题。下面分别详细讲解,并说明它们的联系与应用场景。


一、NumPy 中的字符串数组

NumPy 支持两种主要的字符串类型:

类型

描述

创建方式

'U'(Unicode 字符串)

固定长度 Unicode 字符串(Python 3 默认)

dtype='U10' 表示最多 10 个字符

'S'(字节字符串)

固定长度 ASCII/字节字符串(类似 Python 的 bytes

dtype='S10' 表示 10 字节

⚠️ 注意:NumPy 字符串是 固定长度 的!超长会被截断,不足会用空字符填充。

1. 创建字符串数组

代码语言:python
复制
import numpy as np

# Unicode 字符串 (推荐)
arr_u = np.array(['apple', 'banana', 'cherry'], dtype='U10')
print(arr_u.dtype)  # <U10 → 小端 Unicode,最大 10 字符

# 字节字符串
arr_s = np.array([b'hello', b'world'], dtype='S8')
print(arr_s.dtype)  # |S8 → 8 字节 ASCII 字符串

2. 固定长度行为示例

代码语言:python
复制
a = np.array(['Python', 'NumPy'], dtype='U5')
print(a)  # ['Pytho' 'NumPy'] → 'Python' 被截断为 5 字符!

3. 字符串操作(向量化)

NumPy 提供 np.char 模块进行向量化字符串操作:

代码语言:python
复制
names = np.array(['Alice', 'Bob', 'Charlie'], dtype='U10')

# 转大写
print(np.char.upper(names))        # ['ALICE' 'BOB' 'CHARLIE']

# 替换
print(np.char.replace(names, 'a', 'A'))  # ['Alice' 'Bob' 'ChAr lie'](注意大小写)

# 拼接
print(np.char.add(names, '_user')) # ['Alice_user' 'Bob_user' 'Charlie_user']

✅ 优势:比 Python 循环快得多(尤其大数据量)


二、字节序(Endianness)与字节交换

1. 什么是字节序?

  • 小端(Little-endian, <:低位字节在前(x86 CPU 默认)
  • 大端(Big-endian, >:高位字节在前(网络协议、某些嵌入式系统)

例如:整数 0x12345678 在内存中的存储:

字节序

内存顺序(低地址 → 高地址)

小端

78 56 34 12

大端

12 34 56 78

2. NumPy 中的字节序标识

NumPy dtype 的字符串表示包含字节序前缀:

代码语言:python
复制
a = np.array([1, 2, 3], dtype='<i4')  # 小端 32 位整数
b = np.array([1, 2, 3], dtype='>i4')  # 大端 32 位整数

print(a.dtype.str)  # '<i4'
print(b.dtype.str)  # '>i4'
  • <:小端(little-endian)
  • >:大端(big-endian)
  • =:本机字节序(默认)
  • |:不适用(如字符串、布尔值)

3. 为什么要字节交换?

  • 跨平台数据交换:从大端机器读取的数据在小端机器上需转换
  • 读取二进制文件:如科学仪器、网络抓包、旧系统导出的数据
  • GPU/加速器要求特定字节序

三、NumPy 中的字节交换操作

方法 1:.byteswap() —— 返回新数组(可选 in-place)

代码语言:python
复制
a = np.array([1, 256, 65536], dtype='=i4')  # 本机字节序
print(a.view('uint8'))  # 查看原始字节(假设小端): [1,0,0,0, 0,1,0,0, ...]

# 字节交换(返回副本)
b = a.byteswap()
print(b.view('uint8'))  # [0,0,0,1, 1,0,0,0, ...] → 变成大端字节序

# in-place 交换(修改原数组)
a.byteswap(inplace=True)

🔍 注意:byteswap() 只交换字节顺序,不改变 dtype 的字节序标记

方法 2:.newbyteorder() —— 创建新 dtype 视图(推荐!)

代码语言:python
复制
a = np.array([1, 2, 3], dtype='<i4')  # 小端

# 创建一个“认为自己是大端”的视图(不复制数据!)
b = a.newbyteorder('>')  # 或 '>'

print(b.dtype)          # >i4
print(b[0])             # 值会按大端解释!可能变成一个奇怪的大数

# 如果你有一个大端数据文件,但当前系统是小端:
# 先用本机序读入,再用 newbyteorder 标记为大端,最后 byteswap 纠正值

方法 3:正确读取外部大端数据(标准流程)

代码语言:python
复制
# 假设你从文件读取了大端整数(但 NumPy 默认按本机序解释)
raw_data = np.frombuffer(file_content, dtype='>i4')  # 直接指定 dtype 为大端!

# 或者:先按本机读,再转换
data_native = np.frombuffer(file_content, dtype='=i4')
data_correct = data_native.byteswap().newbyteorder()  # 交换字节 + 更新 dtype 标记

四、字符串数组与字节序的关系

  • 字符串类型('U', 'S')的字节序标记是 '|',表示“无字节序”(因为字符是逐字节存储的,无需考虑多字节整数那样的字节顺序)。
代码语言:python
复制
s = np.array(['hello'], dtype='U5')
print(s.dtype.byteorder)  # '|' → 不适用
  • 但 Unicode 字符本身可能涉及编码(如 UTF-32 有字节序),不过 NumPy 内部统一处理为 UCS-4(固定 4 字节/字符),并使用本机字节序存储。

✅ 结论:对字符串数组通常不需要手动字节交换,除非你在处理原始二进制编码数据。


五、实战示例:读取二进制文件(含字节序)

假设有一个二进制文件 data.bin,包含 3 个大端 32 位整数:[0x00000001, 0x00000100, 0x00010000]

代码语言:python
复制
# 正确方式:直接指定 dtype 为大端
with open('data.bin', 'rb') as f:
    data = np.frombuffer(f.read(), dtype='>i4')
print(data)  # [1, 256, 65536] → 正确!

# 错误方式(本机小端解释大端数据):
data_wrong = np.frombuffer(f.read(), dtype='<i4')
print(data_wrong)  # [16777216, 65536, 256] → 完全错误!

六、总结速查表

操作

用途

是否复制数据

arr.byteswap()

交换每个元素的字节顺序

默认返回副本,inplace=True 则修改原数组

arr.newbyteorder('>')

创建新 dtype 视图(标记字节序)

❌(视图,不复制)

np.frombuffer(..., dtype='>i4')

读取外部大端数据

取决于底层 buffer

字符串数组(U/S

存储文本

无需字节交换


七、最佳实践建议

  1. 读取二进制数据时,始终明确指定字节序(如 '>f4' 表示大端 float32)
  2. 不要对字符串数组做字节交换(无意义且可能破坏编码)
  3. 使用 arr.dtype.byteorder 检查当前字节序
  4. 跨平台传输 NumPy 数组时,优先使用 .npy 格式(自动处理字节序)

掌握 NumPy 的字符串数组和字节序机制,能让你安全高效地处理科学计算、嵌入式数据、网络协议等真实场景中的二进制与文本数据!💾🌐

后续

本文主要讲述了numpy数组副本和视图。python过渡项目部分代码已经上传至gitee,后续会逐步更新,主要受时间原因限制,当然自己也可以克隆到本地学习拓展。

资料关注

公众号:咚咚王

《Python编程:从入门到实践》

《利用Python进行数据分析》

《算法导论中文第三版》

《概率论与数理统计(第四版) (盛骤) 》

《程序员的数学》

《线性代数应该这样学第3版》

《微积分和数学分析引论》

《(西瓜书)周志华-机器学习》

《TensorFlow机器学习实战指南》

《Sklearn与TensorFlow机器学习实用指南》

《模式识别(第四版)》

《深度学习 deep learning》伊恩·古德费洛著 花书

《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》

《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》

《自然语言处理综论 第2版》

《Natural-Language-Processing-with-PyTorch》

《计算机视觉-算法与应用(中文版)》

《Learning OpenCV 4》

《AIGC:智能创作时代》杜雨+&+张孜铭

《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》

《从零构建大语言模型(中文版)》

《实战AI大模型》

《AI 3.0》

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 人工智能之数据分析 numpy
  • 前言
  • 一、NumPy 中的字符串数组
    • 1. 创建字符串数组
    • 2. 固定长度行为示例
      • 3. 字符串操作(向量化)
  • 二、字节序(Endianness)与字节交换
    • 1. 什么是字节序?
    • 2. NumPy 中的字节序标识
    • 3. 为什么要字节交换?
  • 三、NumPy 中的字节交换操作
    • 方法 1:.byteswap() —— 返回新数组(可选 in-place)
    • 方法 2:.newbyteorder() —— 创建新 dtype 视图(推荐!)
    • 方法 3:正确读取外部大端数据(标准流程)
  • 四、字符串数组与字节序的关系
  • 五、实战示例:读取二进制文件(含字节序)
  • 六、总结速查表
  • 七、最佳实践建议
  • 后续
  • 资料关注
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档