现有软件读取目录,经常遇到几种情况。
于是,写了个小界面。新手入门,一般酷爱循环。因为书本上一开始介绍的就是循环,函数,字符串之类的。前几章学完,就找一些实例去练习。慢慢地,认为没有什么问题是一个循环解决不了的。如果有,那就用两个循环解决。于是,嵌套,并列,判断。选择都用上了。
一开始用循环读目录,经常把MATLAB搞死。后来想了好多办法。比如,切割成小文件读,转换格式后读,等等。其实,菜鸟遇到的问题。大牛们以前都遇到过。诸多大牛大多数都被官方收编。逐渐变成了官方开发人员,推出了更多实用工具。
improt导入数据功能早在2006年之前就推出。但不知道有这个功能。最近发现可以用这个函数导入数据,并可以做前期的数据清理。比如字符串切割劈分,等宽劈分,空格等固定字符劈分功能。而且可以读取带不规则分隔符和头文件的数据信息。比如,现有软件导出的*.MIF边界文件。
先说说MATLAB的ui前置。类似clear函数省略为cl前缀用法。
习惯上,有些人在每一个脚本前都要用到以下命令,清理窗口,变量和图形窗口。
%% 经常使用
clc;
clear;
close all;
每次输入比较麻烦,可以用evalin函数代替。
evalin('base','clc;clear;close all')
% 也可以加其他命令
evalin('base','clc;clear;close all;Zmap') % 打开Zmap软件
有点跑偏。简单来说,部分函数前加个ui表示该函数的界面交互调用方式。
简单介绍下uiimport的使用。只需MATLAB界面输入:
uiimport
选择“文件”,导入一个目录。
红色箭头标注的地方需要设置。
三种形式利用导入的数据。一,导入工作空间。二,导出为脚本。三,导出为函数。下面是导出脚本的代码。
filename = 'D:\EqCatlog\CEIC_ML2.EQT';
formatSpec = '%15f%6f%7f%4f%6f%C%[^\n\r]';
fileID = fopen(filename,'r');
dataArray = textscan(fileID, formatSpec, 'Delimiter', '', 'WhiteSpace', ...
'', 'TextType', 'string', 'EmptyValue', NaN, 'ReturnOnError', false);
fclose(fileID);
EqTim = dataArray{:, 1};
EqLat = dataArray{:, 2};
EqLon = dataArray{:, 3};
EqMag = dataArray{:, 4};
EqDeep = dataArray{:, 5};
EqSite = dataArray{:, 6};
clearvars filename formatSpec fileID dataArray ans;
运行时间查看,代码前加tic,代码后toc。
tic
% 上边的代码
toc
时间已过 1.060942 秒。
同样的道理。读取MIF边界文件,效率也极高。首先通过上边的方法生成函数ReadMif.m,然后调用函数转换数据。
B180 = 'D:\Eq\mapData\areaBankuai\版块边界180.MIF';
Bk = ReadMif(B180 , 1, inf); % 路径,开始行,终止行
function D = ReadMif(filename, startRow, endRow)
%IMPORTFILE 将文本文件中的数值数据作为矩阵导入。
% D = ReadMif(FILENAME) 读取文本文件 FILENAME 中默认选定范围的数据。
%
% D = ReadMif(FILENAME, STARTROW, ENDROW) 读取文本文件 FILENAME 的 STARTROW
% 行到 ENDROW 行中的数据。
%
% Example:
% D = ReadMif('版块边界180.MIF', 4, 19580);
%
% 另请参阅 TEXTSCAN。
% 由 MATLAB 自动生成于 2020/03/27 14:43:00
%% 初始化变量。
delimiter = ' ';
if nargin<=2
startRow = 1;
endRow = inf;
end
%% 将数据列作为文本读取:
% 有关详细信息,请参阅 TEXTSCAN 文档。
formatSpec = '%q%q%q%[^\n\r]';
%% 打开文本文件。
fileID = fopen(filename,'r');
%% 根据格式读取数据列。
% 该调用基于生成此代码所用的文件的结构。如果其他文件出现错误,请尝试通过导入工具重新生成代码。
textscan(fileID, '%[^\n\r]', startRow(1)-1, 'WhiteSpace', '', 'ReturnOnError', false);
dataArray = textscan(fileID, formatSpec, endRow(1)-startRow(1)+1, 'Delimiter', delimiter, 'TextType', 'string', 'ReturnOnError', false, 'EndOfLine', '\r\n');
for block=2:length(startRow)
frewind(fileID);
textscan(fileID, '%[^\n\r]', startRow(block)-1, 'WhiteSpace', '', 'ReturnOnError', false);
dataArrayBlock = textscan(fileID, formatSpec, endRow(block)-startRow(block)+1, 'Delimiter', delimiter, 'TextType', 'string', 'ReturnOnError', false, 'EndOfLine', '\r\n');
for col=1:length(dataArray)
dataArray{col} = [dataArray{col};dataArrayBlock{col}];
end
end
%% 关闭文本文件。
fclose(fileID);
%% 将包含数值文本的列内容转换为数值。
% 将非数值文本替换为 NaN。
raw = repmat({''},length(dataArray{1}),length(dataArray)-1);
for col=1:length(dataArray)-1
raw(1:length(dataArray{col}),col) = mat2cell(dataArray{col}, ones(length(dataArray{col}), 1));
end
numericData = NaN(size(dataArray{1},1),size(dataArray,2));
for col=[1,2]
% 将输入元胞数组中的文本转换为数值。已将非数值文本替换为 NaN。
rawData = dataArray{col};
for row=1:size(rawData, 1)
% 创建正则表达式以检测并删除非数值前缀和后缀。
regexstr = '(?<prefix>.*?)(?<numbers>([-]*(\d+[\,]*)+[\.]{0,1}\d*[eEdD]{0,1}[-+]*\d*[i]{0,1})|([-]*(\d+[\,]*)*[\.]{1,1}\d+[eEdD]{0,1}[-+]*\d*[i]{0,1}))(?<suffix>.*)';
try
result = regexp(rawData(row), regexstr, 'names');
numbers = result.numbers;
% 在非千位位置中检测到逗号。
invalidThousandsSeparator = false;
if numbers.contains(',')
thousandsRegExp = '^[-/+]*\d+?(\,\d{3})*\.{0,1}\d*$';
if isempty(regexp(numbers, thousandsRegExp, 'once'))
numbers = NaN;
invalidThousandsSeparator = true;
end
end
% 将数值文本转换为数值。
if ~invalidThousandsSeparator
numbers = textscan(char(strrep(numbers, ',', '')), '%f');
numericData(row, col) = numbers{1};
raw{row, col} = numbers{1};
end
catch
raw{row, col} = rawData{row};
end
end
end
%% 将非数值元胞替换为 NaN
R = cellfun(@(x) ~isnumeric(x) && ~islogical(x),raw); % 查找非数值元胞
raw(R) = {NaN}; % 替换非数值元胞
%% 创建输出变量
D = cell2mat(raw);
dlmwrite('bk.txt',D,'precision','%s','delimiter','\t'); % 数据保存
数据提取避免了循环,速度很快。自己读取CEIC目录56万行,耗时仅1秒。效率远远大于循环读取。MIF文件也仅仅需要5.7秒。
最后。向提供工作便利的所有付出者致敬,向工作中的所有软件开发者致敬。
计算机的发展,虽然给我们带来了诸多便利。但是也让工作花样变得更多,更复杂,更累人,也很无聊。所以,写笔记找点乐子,没想到又花了好多时间。
最后的最后。感谢阅读,如有兴趣,欢迎留言交流哦。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。