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

Numpy——结构化数组和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)

相关文章:

  • Hadoop企业级高可用与自愈机制源码深度剖析
  • Qt Quick快速入门笔记
  • 【Java】使用VarHandler实现无锁Stack
  • 具备强大的数据处理和分析能力的智慧地产开源了
  • 测试开发笔试题 Python 字符串中提取数字
  • C++ 使用 ffmpeg 解码 rtsp 流并获取每帧的YUV数据
  • [特殊字符] FFmpeg 学习笔记
  • 三角形类CTriangle
  • 使用qt 定义全局钩子 捕获系统的键盘事件
  • ApacheSuperset CVE-2023-27524
  • 《短线追涨与低吸技术》速读笔记
  • Java 二维码
  • Web开发主流前后端框架总结
  • (eNSP)配置WDS手拉手业务
  • 激光干涉仪:解锁协作机器人DD马达的精度密码
  • Vue3基础
  • 自动化测试工具playwright中文文档-------18.模拟
  • 解决el-cascader组件下拉选项过长,数据回显无法换行显示的问题
  • 【计算机网络】第3章:传输层—TCP 拥塞控制
  • Bootstrap 5学习教程,从入门到精通,Bootstrap 5 容器(Container)语法知识点及案例代码详解(4)
  • 杭州哪里做网站好/小程序设计
  • 做电影网站要很大的主机空间吗/常州网站建设优化
  • 哪里有免费的网站自己做/seo网站推广方法
  • 做爰的细节描述和过程网站/seo服务哪家好
  • 做网站加入视频无法播放/汽车seo是什么意思
  • wordpress微信付费/优化营商环境 提升服务效能