(三)运动学片段提取
在数据预处理阶段,我们成功对每个文件的异常数据做出了异常处理,下面我们开始对各个文件做运动学片段提取。
在这里首先插一句,其实预处理阶段,我们对数据的异常处理大部分都是以剔除的方式处理的,这种方式有利有弊!利处自然是简单省事,并且一般来说,产生的异常数据都是无效的,留着也没用,反而会影响片段时长的占比。但是弊处也有,那就是很有一部分的有用数据也被处理了。因为可能某段数据只是那么几个时间点异常,导致了整个片段不连续,直接不可以最为被挑选的对象,这样样本容量会减少,从而影响最终的工况曲线的表征能力。
可是,比赛时间有限呀!当时为了节省时间,我还是毫不犹豫地提出了上述情况地异常数据。一共提取到运动学片段 830 + 613 + 547 = 1990 个,这个数量还算比较合理。因为我们总共有 496464 条采集数据,在我们查到的文献里,采集数据量和我们差不多的也只有将近 2000 个运动学片段。
好的,下面开始讲片段提取方法。
运动学片段提取方法
此外,因为怠速段时长不允许超过180s,因为一旦超过180s就视为异常,所以当提取怠速段的时候,并不是两个运动段之间的所有速度为0的片段叫做怠速段。真正的怠速段定义应是,在运动段之前的180s以内的一段持续为0的片段,超过的部分直接忽略掉,而运动段后面是没有怠速段(速度为0)的。那是下一个运动学片段的,或者是多余的。
建模编程
由上面的分析,我们开始定义运动段的模型化的定义。
-
首先,对于一段速度-时间曲线图,我们找到其中连续不为0的片段;
-
然后,找到片段的前一个时间点速度为0且片段的后一个时间点速度也为0的这样的片段,这样的片段很有可能是运动段;
-
接着,找出持续时间大于10s的片段,因为这样的片段才是比较合理的运动段;
-
紧接着,从前一个时间点开始,逐点向前查找,速度是否持续大于0,一直到遇到速度不为0的时刻点,此时怠速段找到,这里有必要提一下毛刺处理,如果没有这个处理,将会因为毛刺,而提前终止怠速段的前向查找,导致怠速段时长变短,最终影响工况曲线构建,所以考虑毛刺的异常处理非常关键。此外,一直等于0也是不可以的,因为超过180s就属于异常,因此一旦长度到了180s就要从那里断开了;
-
最后,把怠速段到运动段这短时间存起来,就得到一个运动学片段了。
为了更直观感受,给一个流程图:
下面给出完整代码:
- 运动学片段提取代码
function kinepart = kinePartDetect(data) datanew = data; % 提取速度 data_temp = cell2mat(datanew(2:end,2)); fprintf('正在查找运动学片段...\n') % 找出速度大于0的数据 v_index = find(data_temp(:,1)>0); % 找出连续的片段 deal_index1 = is_continue(v_index); % 统计连续片段长度 for i = 1:length(deal_index1) index1_length(i) = length(deal_index1{i}); end % 找出超过10s的数据段 deal_index2 = deal_index1(index1_length > 10,1); % 找出前后都为0的,符合要求的运动片段 is_part = zeros(length(deal_index2),1); for i = 1:length(deal_index2) part_start = deal_index2{i,1}(1)-1; part_end = deal_index2{i,1}(end)+1; if (data_temp(part_start)==0) && (data_temp(part_end)==0) is_part(i) = 1; end end deal_index3 = deal_index2(is_part==1,1); kinepart = cell(length(deal_index3),1); % 找出前面180s范围内为0的那一段 for j = 1:length(deal_index3) for k = 1:180 if deal_index3{j,1}(1)-k > 1 %不可以超出索引 if data_temp(deal_index3{j,1}(1)-k) ~= 0 break; end else break; end end now_index = (deal_index3{j,1}(1)-k+1:deal_index3{j,1}(end)+1); kinepart{j,1} = datanew([1,now_index+1],:); end fprintf('一共找到%d个运动学片段!\n',length(deal_index3)); end
按照前面分析的去提取运动学片段
- 判断片段连续
function data_slice = is_continue(data) m = length(data); k = 1; data_slice = cell(m,1); data_slice{1,1} = data(1); for i = 2:m if data(i) - data(i-1) == 1 data_slice{k,1} = [ data_slice{k,1},data(i)]; else k = k+1; data_slice{k,1} = data(i); end end % 多余空行删除 data_slice(all(cellfun(@(x) isempty(x),data_slice),2),:)=[]; end
这个函数在第一问也用到了,十分关键的一个函数,用它可以将一组数,按连续性,分割成不同的片段。
- 处理每个文件
function dealFile(filename) % 载入数据 fprintf('正在导入%s...\n',filename); load([filename,'数据预处理后'],'datanew'); data = datanew; fprintf('导入成功!一共导入%d条数据\n',length(data)-1); % 选取运动学片段 kinepart = kinePartDetect(data); % 保存运动学片段 save([filename,'运动学片段'],'kinepart'); end
- 画运动段图像
function drawKinepartpic(filename) set(gcf,'outerposition',get(0,'screensize')) fprintf('正在导入%s运动学片段...\n',filename); load([filename,'运动学片段'],'kinepart'); for i = 1:4 subplot(2,2,i) data = kinepart{i}; % 读取运动学片段 plotdata = cell2mat(data(2:end,2)); plot(plotdata,'r-','linewidth',2) grid on set(gca,'fontsize',24) xlabel('时间(s)'),ylabel('车速(km/h)'); set(gca,'GridLineStyle','--','GridColor','k','GridAlpha',1) text = sprintf('%s - %s',data{2,1},data{end,1}); % 片段起止时间 axis tight title(text) end print(gcf,'-djpeg','-r300',[filename,'前4个运动学片段']); fprintf('%s前4个运动学片段绘制完成!\n',filename) end
为了展示最后提取到的运动学片段,我们将每个文件提取到的运动学片段中的前四个展示到一起。
- 主程序
%% 准备存储空间 clc,clear,close all filename = {'文件1','文件2','文件3'}; tic for i = 1:length(filename) dealFile(filename{i}); figure(i) drawKinepartpic(filename{i}); fprintf('----------------------\n'); end fprintf('所有文件运动学片段提取完成!\n'); toc
运行结果展示
运行时的画面是这样的:
输出文字如下
正在导入文件1... 导入成功!一共导入518137条数据 正在查找运动学片段... 一共找到830个运动学片段! 正在导入文件1运动学片段... 文件1前4个运动学片段绘制完成! ---------------------- 正在导入文件2... 导入成功!一共导入518279条数据 正在查找运动学片段... 一共找到613个运动学片段! 正在导入文件2运动学片段... 文件2前4个运动学片段绘制完成! ---------------------- 正在导入文件3... 导入成功!一共导入431784条数据 正在查找运动学片段... 一共找到547个运动学片段! 正在导入文件3运动学片段... 文件3前4个运动学片段绘制完成! ---------------------- 所有文件运动学片段提取完成! 时间已过 104.098016 秒。 >>
得到的三幅运动学片段图如下:
下一阶段任务
完成第三问,点击查看
- 本文链接: https://www.cnblogs.com/gshang/p/2019NPMCM-D-3.html
- 版权声明: 本博客所有文章除特别声明外,均采用 CC-BY-NC-SA 4.0 许可协议。转载请注明出处!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix