浅析Numpy.genfromtxt及File I/O讲解
Python 并没有提供数组功能,虽然列表 (list) 可以完成基本的数组功能,但它并不是真正的数组,而且在数据量较大时,使用列表的速度就会慢的让人难受。为此,Numpy 提供了真正的数组功能,以及对数据快速处理的函数。Numpy 还是很多更高级的扩展库的依赖库,例如: Scipy,Matplotlib,Pandas等。此外,值得一提的是:Numpy 内置函数处理数据的速度是 C 语言级别的,因此编写程序时,应尽量使用内置函数,避免出现效率瓶颈的现象。一切计算源于数据,那么我们就来看一看Numpy.genfromtxt 如何优雅的处理数据。
官方文档
Enthought offical tutorial: numpy.genfromtxt
A very common file format for data file is comma-separated values (CSV), or related formats such as TSV (tab-separated values). To read data from such files into Numpy arrays we can use the numpy.genfromtxt function.
案例说明
我们以数字示波器采集的实验产生的三角波 (triangular waveform) 为例,它是包含数据信息的表头,以 .txt 格式存储的文本文件。
Type: raw
Points: 16200
Count: 1
...
X Units: second
Y Units: Volt
XY Data:
2.4000000E-008, 1.4349E-002
2.4000123E-008, 1.6005E-002
2.4000247E-008, 1.5455E-002
2.4000370E-008, 1.5702E-002
2.4000494E-008, 1.5147E-002
...
Python 获取数据的方式有很多:(1) 如果在命令行运行 Python 脚本,你可以用 sys.stdin 和 sys.stdout 以管道 (pipe) 方式传递数据;(2) 可以显式地用代码来读写文件获取数据;(3) 从网页获取数据,也就是所谓的爬虫 (web spider);(4) 使用 API (Application Programming Interface) 获取结构化格式的数据。 而在科学计算领域,更多的是处理实验中所获得的数据,比如:传感器,采集卡,示波器,光谱仪等仪器采集的数据。
案例一:温度传感器 (temperature sensor) 数据
本案例所采用的数据是热敏电阻 (thermistor) 采集的被加热物体的温度信息数据,其以如下格式存储在txt文件中:
2018-02-15 21:31:08.781 49.9492
2018-02-15 21:31:09.296 49.9589
2018-02-15 21:31:09.811 49.964
2018-02-15 21:31:10.326 49.9741
2018-02-15 21:31:10.841 49.983
...
处理文本文件的第一步是通过 open 命令来获取一个文件对象:
file_for_reading = open('thermistor.txt', 'r') # 'r' 意味着只读
file_for_writing = open('thermistor.txt', 'w') # 'w' 是写入
file_for_appending = open('thermistor.txt', 'a') # 'a' 是添加
file_for_xxx.close() # 完成操作后要关闭文件
因为非常容易忘记关闭文件,所以应该在 with 程序块里操作文件,这样结尾处文件会被自动关闭:
with open('thermistor.txt', 'r') as f:
data = function_that_gets_data_form(f) # 获取数据函数
此时,f 已经关闭了,就不能试图使用它啦,然后对数据执行相应的操作即可。
process(data) # 处理数据函数
import csv
with open(r"thermistor.txt","rb") as f:
reader = csv.reader(f,delimiter='\t')
number=[]
time = []
data=[]
for row in reader:
number.append(row[0])
time.append(row[1])
data.append(float(row[2]))
处理文本文件的第三步是检测数据读取格式是否正确,我们可以用如下的方式检测:
>>> print number[0], time[0], data[0]
>>> 2018-02-15 21:31:08.781 49.9492
从输出的首个元素来看,以上的读取数据的方式是没有问题的,但是到这里我们并不能完全放心我们的数据格式:
>>> print number[0:3], time[0:3], data[0:3]
>>> ['\xef\xbb\xbf1', '', '']
['2018-02-15 21:31:08.781', '2018-02-15 21:31:09.296', '2018-02-15 21:31:09.811']
[49.9492, 49.9589, 49.964]
import csv
import codecs
with codecs.open(r"thermistor.txt","rb","utf-8-sig") as f:
reader = csv.reader(f,delimiter='\t')
number=[] time=[] data=[]
for row in reader:
number.append(row[0])
time.append(row[1])
data.append(float(row[2])
此时,我们再以列表形式输出时,就会得到正确的结果:
>>> ['', '', '']
['2018-02-15 21:31:08.781', '2018-02-15 21:31:09.296', '2018-02-15 21:31:09.811']
[49.9492, 49.9589, 49.964]
然后就可以用得到的数据进行处理分析啦~
案例二:示波器 (oscilloscope) 数据
有了上面的经验,我们直接从处理文本文件第二步开始,示波器数据相对上面的数据,复杂的地方在于它包含了表头信息,而这些信息大部分时间是处理数据中不太需要的,它的数据格式如下:
Type: raw
Points: 16200
Count: 1
XInc: 1.23457E-013
XOrg: 2.4000000000E-008
YData range: 1.48000E-001
YData center: 5.00000E-004
Coupling: 50
Ohms XRange: 2.00000E-009
XOffset: 2.4000000000E-008
YRange: 1.44000E-001
YOffset: 5.00000E-004
Date: 15 APR 2018
Time: 16:00:54:74
Frame: 86100C:MY46520443
X Units: second
Y Units: Volt
XY Data:
2.4000000E-008, 1.4349E-002
2.4000123E-008, 1.6005E-002
2.4000247E-008, 1.5455E-002
2.4000370E-008, 1.5702E-002
2.4000494E-008, 1.5147E-002
...
可以看出,“表头”是一些参数信息,真正有用的数据是从 “XY Data:” 下一行开始的,对于这样的数据有两种方法进行读取:(1) 直接跳过“表头”读取数据;(2) 利用正则表达式寻找“表头” 和数据的不同特征进行识别读取。
with open(r"waveform.txt","rb") as f:
lines = f.readlines() x=[] y=[]
for line in lines[18:]:
x.append(float(line.replace("\r\n","").split(",")[0]))
y.append(float(line.replace("\r\n","").split(",")[1]))
通过观察我们发现有效数据是从第19行开始的,于是我们直接从19行开始读取数据,跳过“表头”,以列表形式输出 x 和 y 前3个元素如下:
>>> [2.4e-08, 2.4000123e-08, 2.4000247e-08]
[0.014349, 0.016005, 0.015455] # 数据读取正确
运用正则表达式读取数据的关键在于找到有效数据行的独有特征,这里以 “E-002” 作为有效数据行区别于“表头”的特征,对数据的读取方式如下:
import re
with open(r"waveform.txt","rb") as f:
lines = f.readlines()
x=[]
y=[]
for line in lines:
if re.search('E-002',line):
x.append(float(line.replace("\r\n","").split(",")[0]))
y.append(float(line.replace("\r\n","").split(",")[1]))
同样,以列表形式输出 x 和 y 前3个元素用于检验:
>>> [2.4e-08, 2.4000123e-08, 2.4000247e-08]
[0.014349, 0.016005, 0.015455] # 数据读取正确
注:具体的数据读取方式要根据具体文本文件的特征决定,运用合适的方法才能得到更好的结果。
案例三:二维数据写入
很多时候,经过 process( ) 后的数据,需要备份留用或者供其他程序调用,因此,将处理后的数据写入文本文件也将是关键的一步。根据数据读入的经验,被读入的数据经常存储在 list 中,那么处理后数据也通常存储在 list 中,因此,以 list 的写入作为例子:
x = [1, 2, 3, 4]
y = [2.0, 4.0, 6.0, 8.0] # 参考数据
接下来就要考虑的是要以什么样的格式保存数据,为了更加直观的表现数据的关系,我们将 x,y 分别保存为一列,中间以空格键隔开,那么 csv.writer( ) 将是很好的工具:
xy = {}
for i in range(len(x)):
xy[x[i]] = y[i]
with open(r"15.txt", 'wb') as f:
writer = csv.writer(f,delimiter='\t')
for x, y in xy.items():
writer.writerow([x, y])
为了同时保存 x 和 y 的对应值,这里把 x 和 y 写入字典,x 为键 (key), y 为 值 (value) ,xy 就是 x 和 y 构成的字典。保存后的数据格式如下所示:
1 2.0
2 4.0
3 6.0
4 8.0
案例四:多维数据写入
由于字典的键 (key) 和值 (value) 对应的特殊数据结构,写入二维数据较为方便,对于多维数据,我们就需要构建多维矩阵,或者列表与元组结合的方式录入:
x = [1, 2, 3, 4]
y = [2.0, 4.0, 6.0, 8.0]
z = [3.0, 6.0, 9.0, 12.0]
这里以三维数据为例子。同样,需要将 x,y,z 各一列写入到txt中:
xyz = []
for i in range(len(x)):
xyz.append([x[i],y[i],z[i]])
with open(r"15.txt", 'wb') as f:
writer = csv.writer(f,delimiter='\t')
for x, y, z in xyz:
writer.writerow([x, y, z])
这样,就可以很容易地得到需要的数据格式的文本文件:
1 2.0 3.0
2 4.0 6.0
3 6.0 9.0
4 8.0 12.0
我们已经提到了两种方法读取上述的数据,它们共同点是将数据存储在列表中,正如开头所说,列表在处理大量数据时是非常缓慢的。那么,我们就来看一看 numpy.genfromtxt 如何大显身手。
代码示例
为了得到我们需要的有用数据,我们有两个硬的要求: (1) 跳过表头信息;(2) 区分横纵坐标。
import numpy as np
data = np.genfromtxt('waveform.txt',delimiter=',',skip_header=18)
print data[0:3,0], data[0:3,1]
因为读入的是二维数据,因此利用 numpy 二维数据的切片方式 (Index slicing) 输出各自的前三个数据验证是否读取正确:
[ 2.40000000e-08 2.40001230e-08 2.40002470e-08]
[ 0.014349 0.016005 0.015455]
对数据进行归一化处理后,调用 Matplotlib 画图命令,就可得到图像如下:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(figsize=(8,6))
axes.plot(x, y, 'r', linewidth=3)
axes.set_xlabel('Time(ps)')
axes.set_ylabel('Amplitude[a.u.]')
fig.savefig("triangular.png", dpi=600)
补充
numpy.genformtxt( ) 函数提供了众多的入参,实现不同格式数据的读取,详情可参考:numpy.genfromtxt
此外,numpy 中还提供了将数据存储为 CSV 格式的函数 numpy.savetxt( ),详情可参考:numpy.savetxt
浅析Numpy.genfromtxt及File I/O讲解的更多相关文章
- 用NumPy genfromtxt导入数据
用NumPy genfromtxt导入数据 NumPy provides several functions to create arrays from tabular data. We focus ...
- Mac os fatal error: 'numpy/arrayobject.h' file not found
$ python setup.py install 出错信息如: clang -fno-strict-aliasing -fno-common -dynamic -g -O2 -DNDEBUG -g ...
- python学习之Numpy.genfromtxt
Python 并没有提供数组功能,虽然列表 (list) 可以完成基本的数组功能,但它并不是真正的数组,而且在数据量较大时,使用列表的速度就会慢的让人难受.Numpy 提供了真正的数组功能,以及对数据 ...
- numpy中transpose和swapaxes函数讲解
1 transpose() 这个函数如果括号内不带参数,就相当于转置,和.T效果一样,而今天主要来讲解其带参数. 我们看如下一个numpy的数组: arr=np.arange(16).reshape( ...
- Numpy 系列(十一)- genfromtxt函数
定义输入 genfromtxt的唯一强制参数是数据的源.它可以是字符串,字符串列表或生成器.如果提供了单个字符串,则假定它是本地或远程文件或具有read方法的打开的类文件对象的名称,例如文件或Stri ...
- NumPy之:使用genfromtxt导入数据
目录 简介 genfromtxt介绍 多维数组 autostrip comments 跳过行和选择列 简介 在做科学计算的时候,我们需要从外部加载数据,今天给大家介绍一下NumPy中非常有用的一个方法 ...
- Numpy函数学习--genfromtxt函数
genfromtxt函数 今天学习时遇到了genfromtxt函数 world_alcohol = numpy.genfromtxt("world_alcohol.txt",del ...
- numpy用法小结
前言 个人感觉网上对numpy的总结感觉不够详尽细致,在这里我对numpy做个相对细致的小结吧,在数据分析与人工智能方面会有所涉及到的东西在这里都说说吧,也是对自己学习的一种小结! numpy用法的介 ...
- Numpy - 多维数组(上)
一.实验说明 numpy 包为 Python 提供了高性能的向量,矩阵以及高阶数据结构.由于它们是由 C 和 Fortran 实现的,所以在操作向量与矩阵时性能非常优越. 1. 环境登录 无需密码自动 ...
随机推荐
- [国嵌笔记][013][Mini2440开发板介绍]
系统资源 处理器:三星 S3C2440A ARM9 内存:64M SDRAM Nor Flash:2MB Nand Flash:256MB LCD:3.5寸 分辨率320*240 启动模式 从nan ...
- spring cloud-zuul的Filter详解
在前面我们使用zuul搭建了网关http://blog.csdn.net/liuchuanhong1/article/details/59056278 关于网关的作用,这里就不再次赘述了,我们今天的重 ...
- JQuery常用知识点及示例
1.JQuery 名称解释 JQuery是封装了常用JS操作函数的一个库文件JQuery = Javascript + Query (查询)Jquery意思即指: 强大的DOM节点查询 2.官网:ht ...
- 获取select中的值
分别使用javascript原生的方法和jquery方法<select id="test" name=""> <option value=&q ...
- ADO.NET复习总结(2)--连接池
1. 2. 3.示例:在一百次循环中,执行数据库连接的打开和关闭,使用stopwatch查看所用的时间. using System; using System.Collections.Generic; ...
- get最简单直接粗爆git与github教程
Git是分布式版本控制系统(可以理解为文件管理拓展工具) github一个在线文件托管系统(可以理解为一个在线云盘) 准备工作,在git官网下载git软件件,安装git软件,以windows.为例,下 ...
- Redis-安装、启动
安装Redis 下载redis安装包http://download.redis.io/redis-stable.tar.gz 解压安装包tar xzf redis-stable.tar.gz 安装cd ...
- 捕获arm非托管磁盘虚拟机,并进行还原
背景:非托管磁盘虚拟机"hlmcen69n1",附加了一块100GB的数据磁盘.由于arm非托管磁盘机器无法通过Portal界面直接"Capture",故只能通 ...
- 控制台调用天气API例子
第一步,新建控制台应用程序,然后新建类:WeatherReport: using System; using System.Collections.Generic; using System.Linq ...
- yum错误,Cannot find a valid baseurl for repo: base 和 No more mirrors to try
可能出错原因: 1. yum 配置错误 2. 虚拟机无法连接外网 3. 域名解析没有 如何解决这个错误? 1. 网上找 /ect/yum.conf 和 /etc/yum.repos.d/CentOS- ...