当前位置: 首页 > web >正文

Numpy入门4——结构化数组和Numpy文件

一、结构化数组

1、结构化数组创建的意义
  • ndarray是一种同构数据容器,想要用数组存储不同数据类型的时候会有很不方便,因此诞生了结构化数组
  • 结构化数组提供将数组内单个数据解释为带有任意类型列的表格型结构
  • 主要特点:
    • 可以存储不同类型的数据(整数、浮点数、字符串等)
    • 每个字段有名称和数据类型
    • 支持类似数据库表格的操作
    • 内存布局紧凑,访问高效
2、创建结构化数组
  • 方法一:使用 dtype 直接定义
import numpy as np# 定义数据类型
dt = np.dtype([('name', 'U10'), ('age', 'i4'), ('weight', 'f4')])# 创建结构化数组
data = np.array([('Alice', 25, 55.5), ('Bob', 32, 75.2)], dtype=dt)print(data)
"""
输出:
[('Alice', 25, 55.5) ('Bob', 32, 75.2)]
"""
  • 方法二:从字典创建
# 从字典创建结构化数组
data_dict = {'names': ['Alice', 'Bob', 'Charlie'],'ages': [25, 32, 37],'weights': [55.5, 75.2, 80.1]
}# 先定义 dtype
dt = np.dtype([('names', 'U10'), ('ages', 'i4'), ('weights', 'f4')])# 创建结构化数组
# 创建空/全是0的结构化数组
data = np.zeros(len(data_dict['names']), dtype=dt)
# 此时data的为[('',0,0),('',0,0),('',0,0)]
data['names'] = data_dict['names']# 将字典的name对应的内容添加到结构化数组中name对应的类型
data['ages'] = data_dict['ages'] # 同上
data['weights'] = data_dict['weights']# 同上print(data)persontype = np.dtype({'names':['name', 'age', 'chinese', 'math', 'english'],'formats':['S32','i', 'i', 'i', 'f']}
)# 每一行有五列,每列通过属性名的方式去获取对应的值
# 等价于persontype = [(‘name’,’S32’),(‘age’,’i’),(‘chinese’,’i’),(‘math’,’i’),(‘english’,’f’)]
# 指定ndarray时,dtype(data type)指定为dtype
peoples = np.array([("ZhangFei",32,75,100,90),("GuanYu",24,85,96,88.5),("ZhaoYun",28,85,92,96.5),											("HuangZhong",29,65,85,100)],dtype=persontype)
# peoples也像个二维列表,但是第二个维度可以用字段名去指定元素
# 而不是用数字了,而是像字典一样通过属性名取获取对应的值
ages = peoples[:]['age']  # 等价于 peoples['age']
chineses = peoples[:]['chinese'] # peoples['chinese']
maths = peoples[:]['math']    # peoples['math']
englishs = peoples[:]['english'] # peoples['english']print(peoples)
  • 方法三:从现有数据创建
# 从元组列表创建
data = np.array([('Alice', 25, 55.5), ('Bob', 32, 75.2)],dtype=[('name', 'U10'), ('age', 'i4'), ('weight', 'f4')])
3、访问结构化数组数据
  • 按字段名访问
# 访问所有名字
print(data['name'])  # 输出: ['Alice' 'Bob']# 访问所有年龄
print(data['age'])   # 输出: [25 32]# 访问第一个元素的所有字段
print(data[0])       # 输出: ('Alice', 25, 55.5)
  • 同时访问多个字段
# 访问名字和年龄
print(data[['name', 'age']])
"""
输出:
[('Alice', 25) ('Bob', 32)]
"""
4、字段操作
  • 修改字段值
# 修改年龄
data['age'] = [26, 33]# 修改单个元素的字段
data[1]['weight'] = 76.0
  • 条件筛选(使用方法类似np.where的使用方法)
# 筛选年龄大于30的记录
print(data[data['age'] > 30])
  • 排序(使用numpy自带的sort函数)
# 按年龄排序
print(np.sort(data, order='age'))# 按多个字段排序(先按年龄,再按体重)
print(np.sort(data, order=['age', 'weight']))
  • 字段操作
# 计算平均年龄
print(np.mean(data['age']))# 添加新字段
new_dt = np.dtype(data.dtype.descr + [('height', 'f4')])
new_data = np.zeros(data.shape, dtype=new_dt)
for field in data.dtype.fields:new_data[field] = data[field]
new_data['height'] = [165.5, 180.2]
5、 结构化数组与普通数组的转换
  • 结构化数组转普通数组(直接使用np.array进行转化)
# 提取所有数值字段
numeric_data = np.array([data['age'], data['weight']]).T
  • 普通数组转结构化数组(相当于创建结构化数组的方三)
# 假设有一个普通数组
arr = np.array([[1, 2.5, 'Alice'], [2, 3.7, 'Bob']])# 转换为结构化数组
dt = np.dtype([('id', 'i4'), ('value', 'f4'), ('name', 'U10')])
struct_arr = np.array([tuple(row) for row in arr], dtype=dt)
6、结构化数组的局限性
  • 灵活性:不如 Pandas DataFrame 灵活
  • 功能:缺乏高级数据操作功能(如分组、透视等)
  • 性能:对于某些操作可能不如专门的数据结构高效
  • 内存:字符串字段会占用固定长度的内存

二、Numpy 文件

1、保存到文件
  • save(文件名,数组):保存数组到文件中,若未指定文件的后缀名自动保存为npy文件。
  • savetxt(文件名,数组,其他限制条件):将文件保存到以txt为后缀的文件中
  • savez(文件名,数组,数组):将多个文件保存到一个未压缩的文件中,数组以关键字的形式传入(关键字自定)
  • savez_compressed(文件名,数组):将文件保存到一个已经压缩的文件中
# 保存为文本文件
import numpy as np
names = [ ('Tom', 18, 175), ('Jerry', 22, 180), ('Ben', 21, 170)]
dtype = [('name', 'S10'), ('age', int), ('height', float)]
data = np.array(names, dtype=dtype)  # 创建结构化数组,数据类型为自定义的dtype类型
np.savetxt('data.csv', data, fmt='%s,%d,%.2f', header='name,age,height', comments='')
# data.csv文件内容:# name,age,height# b'Tom',18,175.00# b'Jerry',22,180.00# b'Ben',21,170.00
# 其中的分隔符是,是因为fmt格式将comments冲掉了np.save('structured_data', data) # 使用save进行保存,不用指定后缀,自动添加npy后缀np.savez("array_archive.npz", a=data, b=data) # 同时存多个数组到未压缩的文件,可以使用任意关键字np.savez_compressed("array_archive.npz", a=data, b=data) # 同时存多个数组到已经压缩的文件,可以使用任意关键字
2、从文件加载
  • loadtxt(文件名,使用savetxt时添加的限制条件):读取txt结尾的文件
  • getfromtxt(文件名,限制条件):假如数组文件中有缺失的内容,该方法会将缺失的内容读成nan(nan代表浮点数据类型的数字)
  • load(文件名):读文件的时候必须加上后缀
# 加载二进制文件
data = np.load('structured_data.npy')
print(data) # 输出: NpzFile 'array_archive.npz' with keys: a, b
# 可以看到压缩文件中有a,b
print(data["a"]) # 查看压缩文件中a文件的内容# 从文本文件加载
data = np.genfromtxt('data.csv', delimiter=',', dtype=[('name', 'U10'), ('age', 'i4'), ('weight', 'f4')],skip_header=1)
print(data)
# 输出:[("b'Tom'", 18, 175.) ("b'Jerry'", 22, 180.) ("b'Ben'", 21, 170.)]
3、操作字节文件
  • 操纵字节文件(多半和其余语言进行交互,这种文件可以是音频、视频等任何格式的文件)
  • 此处的字节文件是一个二进制的字节流文件。
import wave  # 导入wave模块(音频模块)
import numpy as npwf = wave.open('alert.wav') # 本地目录下的文件
data = wf.readframes(wf.getnframes()) # 二进制数据 固定用法
data1 = np.frombuffer(data) # 二进制解析成ndarray ,输出:array([], dtype=float64)
# frombuffer函数:将字节流  读成  numpy数组
data1 = np.frombuffer(data, dtype='int64') # array([], dtype=int64)
http://www.xdnf.cn/news/12123.html

相关文章:

  • C++多态与继承实战解析
  • 如何判断是 CPU 密集还是 IO 密集型任务?
  • C++语法系列之IO流
  • JAVA 集合进阶 01 - 05 双列集合
  • FEMFAT许可分析中的关键指标
  • Java直接内存(directMemory)分配与查看
  • DNS解析深入探讨
  • linux扫描所有私有网段shell脚本
  • 2.MySQL基础:SQL语句
  • 【Python实战】零基础实战教程(三) 变量与数据类型
  • 【Python指南】离线安装顽固复杂的第三方库指南
  • Transformers生成文本:max_new_tokens揭秘
  • 第二十三章 Shell的基础语法
  • haribote原型系统改进方向
  • 【Day44】
  • 【向量化模型如何私有化部署】一文说清原理、流程与最佳实践
  • 软件工程专业本科毕业论文模板
  • 龙虎榜——20250604
  • ‌RF Choke(射频扼流圈)
  • 2D 写实交互数字人:多终端实时交互,引领数字化浪潮
  • 告别延迟,拥抱速度:存储加速仿真应用的解决方案【1】
  • 【五子棋在线对战】二.项目结构设计 实用工具类模板的实现
  • 分享国外几个好用的ai网站
  • 普中STM32F103ZET6开发攻略(五)
  • 李沐《动手学深度学习》 | 数值稳定性
  • CATIA-CAD 拆图
  • 【优秀三方库研读】quill 开源库中的命名空间为什么要用宏封装
  • 养老实训中心建设规划:新时代养老服务人才实践能力提升工程
  • 【算法训练营Day06】哈希表part2
  • java判断一个字符串(如 str1)是否在给定的一组字符串