Matlab读取txt数据的实用方法[通俗易懂]

Matlab读取txt数据的实用方法[通俗易懂]

大家好,又见面了,我是你们的朋友全栈君。

需求有个朋友需要我帮忙写个matlab脚本读取100个txt文档的实验数据,这些文档的结构相同,分为四列,从第一列到第四列依次是时间、位置、速度、加速度。读取完数据之后需要对数据进行处理,具体的处理方式是:提取以0.002为采样周期的数据,分类存储起来。

文件内容是这样的:

技术难点技术难点在于,这些文件中的数据是从一个软件中仿真得到的,由于采用的是变步长仿真,因此采样时间不统一,很难采用对时间取余的操作来实现。

解决办法首先对于给定的文档结构,采用textread函数读取四列数据分别存放在四个变量a1,a2,a3,a4中。小伙伴儿可能会问,由于文件头的存在,读取的数据前面几行并不是实际数据,怎么办?好办,把前几行去掉不就行了,使用MATLAB很容易提取。

代码语言:javascript复制[a1,a2,a3,a4]=textread(filename,'%s%s%s%s','headerlines',4);由于读入到matlab中的数据属于文本变量,对应的类型是cell,而我们需要的数据类型是double,怎么办?类型转换吧;处理过程:cell->mat->double

代码语言:javascript复制function res=cell2double(input)

[n,m]=size(input);

res=zeros(n,1);

for i=1:n

temp=cell2mat(input(i));

res(i)=str2double(temp);

end

end重点来了,由于采样时间不是固定的(变步长采样时间有些地方大,有些地方小),因此采用

代码语言:javascript复制mod(time(i),0.002)==0这样的简单判断是不行的,本人试过这种方式来提取数据,结果有的文件提取的数据多,有的文件提取的数据少,无法跟时间进行对齐,确实很让人头疼。

考虑到采样时间精度在0.002秒以下,如果只是采用时间除以0.002取余数,很多数据会被错误判定为不合适,从而丢失数据。怎么办呢?

对时间四舍五入嘛,将时间四舍五入到小数点后3位不就行了。

但是呢,问题又来了,比如采样时间0.0082,0.0084时,则这两个数据都会被加入,这是行不通的,处理的结果依然跟前面的一样。

从四舍五入后的数据中寻找特征吧。对于四舍五入后的时间点,当存在相同的采样时间是只取其中的一个即可,仔细观察可以发现这样的数据特征,每一个满足要求的数据,它的后面一个数据的时间节点总是比它大。

代码就这样写吧:

代码语言:javascript复制 for j=1:time_rows-5-1

if mod(time(j),0.002)==0%能被0.002整除,条件1

if time(j+1)>time(j)%后一个采样时间比前一个大,条件2

tempTime(k)=time(j);

tempPos(k)=pos(j);

tempSpeed(k)=speed(j);

tempAcc(k)=acc(j);

k=k+1;

end

end

end好啦,贴一下完整的代码,仅供参考。

参考代码代码语言:javascript复制clc;

clear all;

N=100;

M=5000;

dataToGetPos=zeros(M,N+1);

dataToGetSpeed=zeros(M,N+1);

dataToGetAcc=zeros(M,N+1);

for i=1:N

str1='result';

str2='.txt';

filename=sprintf('%s%d%s',str1,i,str2);

[a1,a2,a3,a4]=textread(filename,'%s%s%s%s','headerlines',4);

[pos_rows,pos_cols]=size(a2);

[time_rows,time_cols]=size(a1);

[speed_rows,speed_cols]=size(a3);

[acc_rows,acc_cols]=size(a4);

tempPos=zeros(M,1);

tempTime=zeros(M,1);

tempSpeed=zeros(M,1);

tempAcc=zeros(M,1);

time=cell2double(a1(5:time_rows));

pos=cell2double(a2(5:pos_rows));

speed=cell2double(a3(5:speed_rows));

acc=cell2double(a4(5:acc_rows));

time=round(time,3);

k=1;

if i==1

for j=1:time_rows-5-1

if mod(time(j),0.002)==0

if time(j+1)>time(j)

tempTime(k)=time(j);

tempPos(k)=pos(j);

tempSpeed(k)=speed(j);

tempAcc(k)=acc(j);

k=k+1;

end

end

end

[tempPosRows,tempPoscols]=size(tempPos);

if tempPosRows

for l=tempPosRows+1:M

tempPos(l)=0;

tempTime(l)=0;

tempSpeed(l)=0;

tempAcc(l)=0;

end

end

dataToGetPos(:,1)=tempTime;

dataToGetPos(:,2)=tempPos;

dataToGetSpeed(:,1)=tempTime;

dataToGetSpeed(:,2)=tempSpeed;

dataToGetAcc(:,1)=tempTime;

dataToGetAcc(:,2)=tempAcc;

else

for j=1:time_rows-5-1

if mod(time(j),0.002)==0

if time(j+1)>time(j)

tempPos(k)=pos(j);

tempTime(k)=time(j);

tempSpeed(k)=speed(j);

tempAcc(k)=acc(j);

k=k+1;

end

end

end

[tempPosRows,tempPoscols]=size(tempPos);

if tempPosRows

for l=tempPosRows+1:M

tempPos(l)=0;

tempSpeed(l)=0;

tempAcc(l)=0;

end

end

dataToGetPos(:,i+1)=tempPos;

dataToGetSpeed(:,i+1)=tempSpeed;

dataToGetAcc(:,i+1)=tempAcc;

end

disp(['Processing: ',num2str(i/N*100),'%.......']);

end

save dataToGetPos.mat dataToGetPos;

save dataToGetSpeed.mat dataToGetSpeed;

save dataToGetAcc.mat dataToGetAcc;

figure(1)

plot(dataToGetPos(:,1),dataToGetPos(:,2:101));

xlabel('时间/s');

ylabel('位置/mm');

set(gca,'FontSize',13);

figure(2)

plot(dataToGetSpeed(:,1),dataToGetSpeed(:,2:101))

xlabel('时间/s');

ylabel('速度/mm.s^{-1}');

set(gca,'FontSize',13);

figure(3)

plot(dataToGetAcc(:,1),dataToGetAcc(:,2:101))

xlabel('时间/s');

ylabel('加速度/mm.s^{-2}');

set(gca,'FontSize',13);

disp('Done!');数据转换函数:

代码语言:javascript复制function res=cell2double(input)

[n,m]=size(input);

res=zeros(n,1);

for i=1:n

temp=cell2mat(input(i));

res(i)=str2double(temp);

end

end运行以上代码生成下面的几幅图:

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

相关推荐

15分钟弄懂 const 和 #define
yy积分什么时候更新(yy积分几点更新)
印度历年人口数量-印度1959至2018年每年人口数量