今天公司一个漂亮的妹妹,端着笔记本来找我,我一看又是来请教问题的。抱怨Python读数据不好处理。原来,她要读气象部门的micaps的第二类格式数据。查看了相关资料,第二类数据格式属于高空全要素填图数据文件。
文件头:
diamond 2 数据说明(字符串) 年 月 日 时次 层次
总站点数(均为整数)
注:此类数据用于规范的高空填图
数据:
区站号(长整数) 经度 纬度 拔海高度(均为浮点数) 站点级别(整数) 高度 温度 温度露点差 风向 风速(均为浮点数)
数据文件我打开后,显示如下:
她写的代码如下:
file = open('./2086040108', 'r') # 以只读模式打开文件
lines = file.readlines() # 获取所有行并保存到lines列表中
heads = lines[0].split(' ')
print(heads)
ymds = lines[1].split(' ')
print(ymds)
for i in range(2,len(lines)):
datas = lines[i].split(' ')
print(datas)
file.close()
程序经过运行,显示结果如下:
她抱怨使用split函数,使用空格拆分字符串,发现了切分后,出现了许多空的字符串,还有最后一个数据有换行符\n存在。
split() 方法语法:
str.split(str="", num=string.count(str)).
参数
- str -- 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
- num -- 分割次数。默认为 -1, 即分隔所有。
返回值
返回分割后的字符串列表。
看到输出的结果,我也是无语,这样的结果处理起来确实费劲,难怪她抱怨。知道了她抱怨的目的,我指点她把split的空格字符去掉。去掉split的空格字符后,运行效果如下:
看到这里,她的眉头舒展开了。原来这么简单呀。错怪了python,是自己不会灵活使用。她突然又提出一个问题,数据说明、年、月、日 、时次、层次、总站点数这些她都会取出处理,但是后面的123*10的数据如何变成123*10数组呢?
这个就更简单了。
data=[]
for i in range(2,len(lines)):
datas = lines[i].split()
data.append(datas)
# print(datas)
file.close()
print(len(data),len(data[0])) #表示一个123x10的二维数组。
print(data[1][7]) #14.0,14.0,第二行第8个数字,验证
从上面的数据的截图可以看出,数据区第二行第8个数字确实是14.0
她冲我微微一笑,老师真厉害!还有什么好的办法读它呢?
import numpy as np
file = open('./2086040108', 'r') # 以只读模式打开文件
content = file.read() # 所有内容保存在content中
file.close()
datas = content.split()
file.close()
head = datas[0:9]
num = int(head[8])
datas = datas[9:]
datas = np.array(datas)
data = datas.reshape(num, 10)
print(data[1][7]) #14.0,第二行第8个数字,验证
从上面的数据截图可以看出,数据区第二行第8个数字确实是14.0
这个办法更精炼!老师你太厉害了。有了小美妹的称赞,我也有点得意忘形。
我原以为,今天她不会再来找我了,没想到下午,趁着我空闲,她又来了。
原来,她的数据格式变了,告诉我下面的数据文件,是格式化保存的数据,每行的数据格式如下:
区站号(5)、经度(6)、纬度(6)、拔海高度(6)、站点级别(2)、高度(7)、温度(7)、温度露点差(7)、风向(7)、风速(7),括号内是要素占的位置数。这种格式该如何读取?
我仔细一看,数据之间不是用空格隔开,而是用固定的宽度保存数据,我明白了,原来气象上的数据处理多用Fortran程序编写,格式化输出写文件是常见的办法,前面几个要素都是挨着一起了,这样写的目的,是为了节省磁盘空间。如果用Fortran写,就非常简单,格式化读入就行了。但是python就没有相应的函数,有点麻烦,代码如下:
file = open('./2086040108.dat', 'r') # 以只读模式打开文件
lines = file.readlines() # 获取所有行并保存到lines列表中
file.close()
station=[]
lon=[]
lat=[]
elevation=[]
category=[]
high=[]
temp=[]
diff=[]
dd=[]
ff=[]
# 区站号(5)、经度(6)、纬度(6)、拔海高度(6)、站点级别(2)、高度(7)、温度(7)、温度露点差(7)、风向(7)、风速(7)
for i in range(len(lines)):
tt = lines[i]
station.append(tt[0:5].strip())
lon.append(tt[5:11].strip())
lat.append(tt[11:17].strip())
elevation.append(tt[17:23].strip())
category.append(tt[23:25].strip())
high.append(tt[25:32].strip())
temp.append(tt[32:39].strip())
diff.append(tt[39:46].strip())
dd.append(tt[46:53].strip())
ff.append(tt[53:60].strip())
file.close()
至此,她的疑问解除,微笑着满意地走了。当个老师不容易呀。不管怎么样,这给了我写头条的素材,整理出来供粉丝们参考。