很久以前的做过的东西,想想还是扔过来复习记录一下。
任务:验证天气预报温度数据准确性,即将天气预报数据与当日观测站数据对比
数据处理目标:将气象站点的观测数据与爬取的预报数据匹配并拼接,便于后续的预报准确率处理。
图1 观测气象站点数据
图2 爬取的天气预报数据
下面开始:
手头上的天气预报数据为38×3=114个,以地点拼音命名,如"akesu.csv",站点数据95个,以站号命名,如"50136.xlsx",另有一台站与地点对应xls文件,且并不是所有的站点数据都有对应天气预报数据。
那么首先筛选出同时拥有天气预报数据与站点数据的地点,并将站点地名对应,这部分我是用matlab实现(也可以用R,因为先前打算用matlab并写好了代码就没再写了,这里使用了strsplit、strfind函数对字符串进行切割匹配:
rawDataNum,rawDataStr]=xlsread('D:\大三\观测站数据\站名与站号对于.xls','C1:D99');
str='D:\大三\data\3new\';
files=dir(strcat(str,'*.csv'));
n=length(files);
filename=cell(1,n);
for i=1:length(files)
a=strsplit(files(i).name,'.');
filename{i}=a{1};
end
std=cell(99,1);
for i=1:99
std{i}=num2str(rawDataNum(i));
end
data=[rawDataStr,std];
filename=filename';
t=1;
for i=1:n
idx=find(cellfun(@(x) ~isempty(strfind(x,filename{i})), rawDataStr));
if ~isempty(idx)
d{t,1}=data{idx,1};
d{t,2}=data{idx,2};
t=t+1;
end
end
由于R语言读取xls、xlsx文件需要java环境,为了方便以利用matlab将xlsx转为csv)
台站数据导入时,由于excel数据格式原因,导入的日期显示为五位数,非正常日期显示形式,经过各种试探查找,使用以下语句转化:
as.Date(x,origin="1899/12/30")
解决
放松没多久,又有新的问题,在R中日期默认格式为"2011-01-01",而预报数据读取格式为"2011/1/1"与"2011年1月1日”,对于前者,使用 as.Date(x)即可,对于后者,as.Date(“2011年1月1日”, “%Y年%m月%d日”)
查阅资料,R语言常用时间处理包有 “zoo"、"lubridate”,其中"lubridate"包unique(ymd_hms(date1),ymd_hms(date2))语句可对时间变量取交集匹配。
ps:安装zoo包时发生版本错误,需要手动安装,具体步骤参考:https://blog.csdn.net/lym152898/article/details/77572163
lubridate包已不适用与3.5、3.6版本R,而R语言最大的特点是包的使用,再次陷入僵局。
R语言另一个特点是数据类型多,数据类型的转换方便,于是采用以下小白(菜鸡)方法:
将时间格式转为"character"类型→直接利用intersect取交集→for循环匹配
这部分报错很多,主要是数据本身一些问题,一般而言其实可以使用:
merge(a,d,by="V1",all=F)
进行拼接,不过并不适用于这个数据,为此不得不写循环:
path1='D:/大三/data/'
path2='D:/大三/data/3new/'
m<-read.csv('D:/大三/观测站数据/match.csv',header=F)
m<-as.matrix(m)
library(stringr)
m[,1]<- str_replace(m[,1], "'","")
m[,2]<- str_replace(m[,2], "'","")
m[,1]<- paste(m[,1],'.csv',sep='')
m[,2]<- paste(m[,2],'.csv',sep='')
fileName1 = dir(path1)
fileName2 = dir(path2)
d3<-list()
t<-1
for (i in 16:length(fileName2))
{
if(setequal(which(m[,1]==fileName2[i]),integer(0)))
next;
a<-read.csv(file = paste(path2,fileName2[i],sep = ''),header = T)
fileName<-m[which(m[,1]==fileName2[i]),2]
if(length(fileName>1))
fileName=fileName[1]
d<-read.csv(file = paste(path1,fileName,sep=""),header=F)
b<-as.Date(d$V1,origin="1899/12/30")
c<-as.character(a$V1)
c<-gsub('/','-',c)
library('stringr')
c<-as.Date(c)
a$V1<-c
d$V1<-b
a<-as.matrix(a)
d1<-as.matrix(d)
d2<-matrix()
b<-as.character(b)
c<-as.character(c)
p<-intersect(b,c)
if (length(p)!=0)
{
d2<-matrix(0,nrow = length(p),ncol =30 )
for (j in 1:length(p))
{
mm<-which(b==p[j])
n<-which(c==p[j])
if (length(mm)>1|length(n)>1)
{
mm=mm[1]
n=n[1]
}
s<-c(a[n,1:13],d1[mm,2:18])
d2[j,]<-as.vector(s)
}
}
d3[[t]]<-d2
write.csv(d3[t],file = paste(path3,fileName2[i],sep = ''))
t<-t+1
}
这是两年半前大三时所写的代码和任务,如今看来其实很幼稚,当时得出的结论是1、在学习像R、matlab这种语言,一定要查明实现这种功能是否有类似函数解决
2、R语言的处理数据类型时,涉及大量数据转换细节,只有多用才能较为熟练使用
虽然当时处理时叫苦连天,不过从现在的目光看,这种类型的气象数据处理已经是很基本的操作了,之后我的数据处理变成了nc数据/卫星数据/栅格数据,对于气象站点数据的处理已经基本不做了,之后的方向也应该注重于卫星数据和模式上。不过气象站点数据的处理算是我的编程入门了,如今想来,还有些怀念。