Numpy入门[18]——数组读写
admin
2024-03-18 13:38:59

Numpy入门[18]——数组读写

参考:

  • https://ailearning.apachecn.org/

使用Jupyter进行练习

import numpy as np

空格(制表符)分割的文本

假设有这样的一个空白分割的文件:

%%writefile myfile.txt
2.1 2.3 3.2 1.3 3.1
6.1 3.1 4.2 2.3 1.8
Writing myfile.txt

为了生成数组,先将数据转化成一个列表组成的列表,再将这个列表转换为数组:

data = []
with open('myfile.txt') as f:# 每次读一行for  line in f:fileds = line.split()row_data = [float(x) for x in fileds]data.append(row_data)
data = np.array(data)
data
array([[2.1, 2.3, 3.2, 1.3, 3.1],[6.1, 3.1, 4.2, 2.3, 1.8]])

更简便的是使用 loadtxt 方法:

data = np.loadtxt('myfile.txt')
data
array([[2.1, 2.3, 3.2, 1.3, 3.1],[6.1, 3.1, 4.2, 2.3, 1.8]])

逗号分隔文件

%%writefile myfile.txt
2.1, 2.3, 3.2, 1.3, 3.1
6.1, 3.1, 4.2, 2.3, 1.8
Overwriting myfile.txt

对于逗号分隔的文件(通常为.csv格式),我可以稍微修改之前繁琐的过程,将 split 的参数变成 ','即可。

不过,loadtxt 函数也可以读这样的文件,只需要制定分割符的参数即可:

data = np.loadtxt('myfile.txt', delimiter=',')
data
array([[2.1, 2.3, 3.2, 1.3, 3.1],[6.1, 3.1, 4.2, 2.3, 1.8]])

loadtxt函数

loadtxt(fname, dtype=, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0) 

delimiter 就是刚才用到的分隔符参数。

skiprows 参数表示忽略开头的行数,可以用来读写含有标题的文本

%%writefile myfile.txt
X Y Z MAG ANG
2.1 2.3 3.2 1.3 3.1
6.1 3.1 4.2 2.3 1.8
Overwriting myfile.txt
np.loadtxt('myfile.txt', skiprows=1)
array([[2.1, 2.3, 3.2, 1.3, 3.1],[6.1, 3.1, 4.2, 2.3, 1.8]])

此外,有一个功能更为全面的 genfromtxt 函数,能处理更多的情况,但相应的速度和效率会慢一些。

genfromtxt(fname, dtype=, comments='#', delimiter=None, skiprows=0, skip_header=0, skip_footer=0, converters=None, missing='', missing_values=None, filling_values=None, usecols=None, names=None, excludelist=None, deletechars=None, replace_space='_', autostrip=False, case_sensitive=True, defaultfmt='f%i', unpack=None, usemask=False, loose=True, invalid_raise=True)

loadtxt的更多特性

%%writefile myfile.txt-- BEGINNING OF THE FILE
% Day, Month, Year, Skip, Power
01, 01, 2000, x876, 13 % wow!
% we don't want have Jan 03rd
04, 01, 2000, xfed, 55
Overwriting myfile.txt
data = np.loadtxt('myfile.txt', skiprows=1,        #忽略第一行dtype=np.int64,    #数组类型delimiter=',',     #逗号分割usecols=(0,1,2,4), #指定使用哪几列数据comments='%'       #百分号为注释符)
data
array([[   1,    1, 2000,   13],[   4,    1, 2000,   55]], dtype=int64)

loadtxt自定义转换方法

%%writefile myfile.txt
2010-01-01 2.3 3.2
2011-01-01 6.1 3.1
Overwriting myfile.txt

假设我们的文本包含日期,我们可以使用 datetimeloadtxt 中处理:

import datetimedef date_converter(s):return datetime.datetime.strptime(s.decode('ascii'), "%Y-%m-%d")data = np.loadtxt('myfile.txt',dtype=object, #数据类型为对象converters={0:date_converter,  #第一列使用自定义转换方法1:float,           #第二第三使用浮点数转换2:float})data
array([[datetime.datetime(2010, 1, 1, 0, 0), 2.3, 3.2],[datetime.datetime(2011, 1, 1, 0, 0), 6.1, 3.1]], dtype=object)
import os
os.remove('myfile.txt')

读写各种格式的文件

如下表所示:

文件格式使用的包函数
txtnumpyloadtxt, genfromtxt, fromfile, savetxt, tofile
csvcsvreader, writer
Matlabscipy.ioloadmat, savemat
hdfpytables, h5py
NetCDFnetCDF4, scipy.io.netcdfnetCDF4.Dataset, scipy.io.netcdf.netcdf_file
文件格式使用的包备注
wavscipy.io.wavfile音频文件
jpeg,png,…PIL, scipy.misc.pilutil图像文件
fitspyfits天文图像

将数组写入文件

savetxt 可以将数组写入文件,参数如下:

savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', footer='', comments='# ')

示例:

data = np.array([[1,2], [3,4]])
def output(file):with open(file) as f:for line in f:print(line)
np.savetxt('out1.txt', data)
print("默认输出")
output('out1.txt')
np.savetxt('out2.txt', data, fmt="%d") #保存为整数
print('保存为整数')
output('out2.txt')
np.savetxt('out3.txt', data, fmt="%.2f", delimiter=',') #保存为2位小数的浮点数,用逗号分隔
print('保存为2位小数的浮点数,用逗号分隔')
output('out3.txt')data2 = np.array([[1+1j,2], [3,4]])np.savetxt('out4.txt', data2, fmt="%.2f", delimiter=',') #保存为2位小数的浮点数,用逗号分隔
print('输出复数')
output('out4.txt')
默认输出
1.000000000000000000e+00 2.000000000000000000e+003.000000000000000000e+00 4.000000000000000000e+00保存为整数
1 23 4保存为2位小数的浮点数,用逗号分隔
1.00,2.003.00,4.00输出复数(1.00+1.00j), (2.00+0.00j)(3.00+0.00j), (4.00+0.00j)

移除生成的文件。

import os
os.remove('out1.txt')
os.remove('out2.txt')
os.remove('out3.txt')
os.remove('out4.txt')

Numpy二进制格式

数组可以储存成二进制格式,单个的数组保存为 .npy 格式,多个数组保存为多个.npy文件组成的 .npz 格式,每个 .npy 文件包含一个数组。

与文本格式不同,二进制格式保存了数组的 shape, dtype 信息,以便完全重构出保存的数组。

保存的方法:

  • save(file, arr) 保存单个数组,.npy 格式
  • savez(file, *args, **kwds) 保存多个数组,无压缩的 .npz 格式
  • savez_compressed(file, *args, **kwds) 保存多个数组,有压缩的 .npz 格式

读取的方法:

  • load(file, mmap_mode=None) 对于 .npy,返回保存的数组,对于 .npz,返回一个名称-数组对组成的字典。

单个数组的读写

a = np.array([[1.0,2.0], [3.0,4.0]])fname = 'afile.npy'
np.save(fname, a)
aa = np.load(fname)
aa
array([[1., 2.],[3., 4.]])
# 删除
os.remove('afile.npy')

二进制与文本大小比较

a = np.arange(10000.)
np.savetxt('a.txt',a)
print('文本文件大小:',os.stat('a.txt').st_size)
np.save('a.npy', a)
print('二进制文件大小:',os.stat('a.npy').st_size)
# 删除生成的文件
os.remove('a.npy')
os.remove('a.txt')
文本文件大小: 260000
二进制文件大小: 80128

可以看到,二进制文件大约是文本文件的三分之一。

保存多个数组

a = np.array([[1.0,2.0], [3.0,4.0]])
b = np.arange(1000)
np.savez('data.npz', a=a, b=b)
# 查看包含的文件
!unzip -l data.npz
Archive:  data.npzLength      Date    Time    Name
---------  ---------- -----   ----160  1980/01/01 00:00   a.npy4128  1980/01/01 00:00   b.npy
---------                     -------4288                     2 files
# 载入数据
data = np.load('data.npz')
# 载入后可以像字典一样进行操作
# data['a']
data['b'].shape
(1000,)

压缩文件

print('当数据比较整齐时')
a = np.arange(20000.)
np.savez('a.npz', a=a)
print('文件压缩前大小:',os.stat('a.npz').st_size)
np.savez_compressed('a2.npz', a=a)
print('文件压缩后大小:',os.stat('a2.npz').st_size)
print('压缩倍数:',os.stat('a.npz').st_size/os.stat('a2.npz').st_size)
当数据比较整齐时
文件压缩前大小: 160256
文件压缩后大小: 26908
压缩倍数: 5.955700906793519
print('当数据比较混乱时')
a = np.random.rand(20000)
np.savez('a.npz', a=a)
print('文件压缩前大小:',os.stat('a.npz').st_size)
np.savez_compressed('a2.npz', a=a)
print('文件压缩后大小:',os.stat('a2.npz').st_size)
print('压缩倍数:',os.stat('a.npz').st_size/os.stat('a2.npz').st_size)
当数据比较混乱时
文件压缩前大小: 160256
文件压缩后大小: 151109
压缩倍数: 1.0605324633211788
os.remove('a.npz')
os.remove('a2.npz')

相关内容

热门资讯

微软警告“Dirty Frag... IT之家 5 月 13 日消息,安全研究人员 Hyunwoo Kim 此前发现一项名为“Dirty ...
Ubuntu 与 Fedora... 如果你打算尝试 Linux,或想换个发行版,Ubuntu 和 Fedora 几乎是绕不开的选项。它们...
“一盔一带 安全同行”交通安全... 广大榆社市民朋友们: 出行安全,是家人最深的牵挂,是文明交通最基本的底线。在日常出行中,安全头盔与安...
原创 撒... 撒贝宁重庆带娃被偶遇,奶爸日常引热议 最近,重庆成了不少明星的热门选择。有网友分享,5月9日,撒贝宁...
不敢相信!金华这里要炸场了!6... 2026中国(金华山)国际 露 营 大 会 活动预告2.0 Time:5.16-5.17 “新场景、...