第3章MATLAB数据管理 浏览历年数学建模竞赛赛题可以发现,这些赛题总是附有大量的数据,在用MATLAB进行编程计算时,不可避免地要涉及数据的导入导出问题。通常情况下,数据文件为记事本文件(TXT文件)和Excel文件,本章通过具体案例介绍MATLAB与这两种类型的文件之间的数据交换。 3.1利用数据导入向导导入数据 MATLAB中提供了基于界面操作的数据导入向导,可以很方便地导入外部数据。不同版本下,数据导入向导的界面及使用方法不尽相同,这里以MATLAB R2020a(即MATLAB 9.8)版本为例,介绍数据导入向导的使用方法。 3.1.1利用数据导入向导导入TXT文件 数据导入向导适合导入排列整齐、文字说明在数据前面的数据文件,见下例。 【例3.11】TXT文件“2006平均气温.txt”中包含以下内容: 115主要城市平均气温 (2006年) 单位:摄氏度 城市1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 北京-1.9 -0.9 8.0 13.5 20.4 25.9 25.9 26.4 21.8 16.1 6.7 -1.0 天津-2.7-1.47.513.220.326.425.926.421.316.26.5-1.7 石家庄-0.91.610.315.121.327.427.025.921.817.88.00.4 太原-3.6-0.46.814.519.123.225.723.117.413.44.4-2.5 …… 如图1.11所示,单击MATLAB工作界面上的导入数据(Import Data)图标,弹出如图3.11所示界面。 图3.11数据文件选择界面 选择数据文件“2006平均气温.txt”,然后单击“打开”按钮,弹出如图3.12所示界面。该界面用来导入TXT数据文件,一切操作都是可视化的。当用户选择的数据文件中包含可读取的数据时,数据预览区会显示相应的数据。导入类型中有5个选项: 表、列向量、数值矩阵、字符串数组和元胞数组。在导入范围编辑框中,用户可以指定数据所在的单元格区域,形如“A4:M34”。界面的中上偏右区域是导入规则编辑区,通过单击规则条目后面的“+”或“-”,可增加或删除一个规则条目。图3.12中显示的默 认规则条目为“用非数NaN替换无法导入的元胞”,表示在导入数据时将无法导入的数据用NaN代替。用户可通过“替换”和“无法导入的元胞”后面的下拉菜单查看可用的规则条目,并通过设置适当的规则条目来替换或过滤某些行和列。界面的左上角区域是列分隔符设置区,默认情况下,数据导入向导会自动识别数据文件中的列分隔符,不需要用户设定,当然用户也可以通过列分隔符设置区的下拉菜单和单选框自定义列分隔符,若改变列分隔符,导入结果可能会随之改变。当用户设置好输出类型、导入范围和导入规则后,只需单击导入按钮即可将数据导入MATLAB工作空间。如果选择导入列向量,则每列数据对应一个变量,默认变量名为VarNamei,i(i=1,2,…)为列序号; 如果选择导入表、数值矩阵、字符串数组或元胞数组,则将全部数据导入为一个变量,默认变量名为untitled。用户可在变量名编辑区输入自定义变量名。 图3.12数据导入向导界面(TXT) 在用户通过图3.12所示界面导入数据的同时,MATLAB执行一系列读取数据的代码,这些代码也是可视化的。单击“操作类型”下拉菜单,可以看到4个选项: 导入数据、生成实时脚本、生成脚本和生成函数。其中“导入数据”选项用来导入数据,其功能相当于单击导入按钮; “生成脚本”选项用来生成与界面操作相关的脚本文件; “生成函数”选项用来生成与界面操作相关的函数文件,这些文件中均包含了与界面操作相对应的MATLAB代码,可作为标准函数使用。 3.1.2利用数据导入向导导入Excel文件 【例3.12】把Excel文件“概率统计成绩.xls”中的数据导入MATLAB工作空间。文件中的数据格式如图3.13所示。 图3.13Excel数据表格 单击MATLAB工作界面上的导入数据(Import Data)图标 ,弹出如图3.11所示界面。选择数据文件“概率统计成绩.xls”,然后单击“打开”按钮,弹出如图3.14所示界面,该界 图3.14数据导入向导界面(Excel) 面用来导入Excel电子表格,一切操作也都是可视化的。当用户的Excel文件中有多个非空工作表时,可通过单击工作表标签来选择要导入的工作表,数据预览区会显示相应的数据。导入类型、导入范围、导入规则、导入按钮和操作类型的使用说明同上。 3.2调用函数读取外部数据 MATLAB中用于读取TXT和Excel数据文件的常用函数如表3.21所示。 表3.21MATLAB中读取数据文件的常用函数 函数名 说明 函数名 说明 load 从文本文件导入数据到MATLAB工作空间 fopen 打开文件,获取打开文件的信息 importdata 从文本文件或特殊格式二进制文件(如图片、AVI视频等)读取数据 fclose 关掉一个或多个打开的文件 readmatrix 从数据文件中读取数据 fgets 读取文件中的下一行,包括换行符 readtable 读取外部数据,创建表格型数组 fgetl 读取文件中的下一行,不包括换行符 sscanf 按指定格式从字符串中读取数据 fscanf 按指定格式从文本文件中读取数据 xlsread 从Excel文件中读取数据 textscan 按指定格式从文本文件或字符串中读取数据 3.2.1调用readmatrix函数读取TXT数据文件 readmatrix函数的调用格式如下: A = readmatrix(filename) A = readmatrix(filename,opts) A = readmatrix(___,Name,Value) filename为字符串,用来指定文件名,若文件名中不包含文件完整路径,则数据文件一定得在当前目录或MATLAB搜索路径下才行。opts为文件导入选项,是由 detectImportOptions 函数所创建的 SpreadsheetImportOptions、DelimitedTextImportOptions 或 FixedWidthImportOptions 对象,具体创建方法可参考如下示例: >> opts = detectImportOptions('学生信息数据.txt')% 创建文件导入选项 opts = DelimitedTextImportOptions - 属性: 格式 属性: Delimiter: {','} Whitespace: '\b\t ' LineEnding: {'\n''\r''\r\n'} CommentStyle: {} ConsecutiveDelimitersRule: 'split' LeadingDelimitersRule: 'keep' EmptyLineRule: 'skip' Encoding: 'GB18030' 替换 属性: MissingRule: 'fill' ImportErrorRule: 'fill' ExtraColumnsRule: 'addvars' 变量导入 属性: VariableNames: {'Name', 'Age', 'Height' ... and 1 more} VariableTypes: {'char', 'double', 'double' ... and 1 more} SelectedVariableNames: {'Name', 'Age', 'Height' ... and 1 more} VariableOptions: Show all 4 VariableOptions Access VariableOptions sub-properties using setvaropts/getvaropts PreserveVariableNames: false 位置 属性: DataLines: [2 Inf] VariableNamesLine: 1 RowNamesColumn: 0 VariableUnitsLine: 0 VariableDescriptionsLine: 0 要显示该表的预览,请使用 preview >> preview('学生信息数据.txt',opts) % 预览文件中的数据 ans = 5×4 table NameAgeHeightWeight {'和平' }1817065 {'谢润和'}1616052 {'韩宇浩'}1516050 {'金志文'}2017570 {'邓泽楷'}1517256 Name和Value是可选的、成对出现的参数名和参数值,用来设置读取数据的选项。例如,将Name和Value分别设置为'NumHeaderLines' 和5,则表示表格数据的前五行是标题行。 【例3.21】TXT文件“两段数据与文字.txt”中包含以下内容: 这是两行头文件, 你可以选择跳过,读取后面的数据。 1.096975,0.635914,4.045800,4.483729,3.658162,7.635046 6.278964,7.719804,9.328536,9.727409,1.920283,1.388742 6.962663,0.938200,5.254044,5.303442,8.611398,4.848533 这里还有两行文字说明和两行数据, 看你还有没有办法! 5.472155,1.386244,1.492940 8.142848,2.435250,9.292636 本文件中有两段数据和两段文字说明,数据间用逗号作为分隔符,这是包含数值和文本混合类型的数据文件,默认情况下,readmatrix 将数据作为数值数组导入,数据间的文本及不等长部分将以NaN(缺失数据)填充。 >> data = readmatrix('两段数据与文字.txt')% 读取记事本文件中的数据矩阵 data = 1.09700.63594.04584.48373.65827.6350 6.27907.71989.32859.72741.92031.3887 6.96270.93825.25405.30348.61144.8485 NaNNaNNaNNaNNaNNaN NaNNaNNaNNaNNaNNaN 5.47221.38621.4929NaNNaNNaN 8.14282.43529.2926NaNNaNNaN >> d1 = data(1:3,:)% 提取第一段数据 d1 = 1.09700.63594.04584.48373.65827.6350 6.27907.71989.32859.72741.92031.3887 6.96270.93825.25405.30348.61144.8485 >> d2 = data(6:7,1:3)% 提取第二段数据 d2 = 5.47221.38621.4929 8.14282.43529.2926 3.2.2调用textscan函数读取TXT数据文件 调用textscan函数读取数据的一般步骤是: 调用fopen函数按指定格式打开文件,并获取文件标识符,调用textscan函数读取文件内容,然后调用fclose函数关闭文件。 1. 调用fopen函数打开文件 fopen函数用于打开一个文件,也可用于获取已打开文件的信息。默认情况下,fopen函数以读写二进制文件方式打开文件。fopen函数用于打开文本文件的调用格式如下: fid = fopen(filename, permission) 上述代码以指定方式打开一个文件。参数filename是一个字符串,用来指定文件名,可以包含完整路径,也可以只包含部分路径(在MATLAB搜索路径下)。permission也是一个字符串,用来指定打开文件的方式,可用的方式如表3.22所示。 表3.22打开文本文件的方式列表 允许的打开方式 (permission) 说明 'rt' 以只读方式打开文件,这是默认情况 'wt' 以写入方式打开文件,若文件不存在,则创建新文件并打开,原文件内容会被清除 'at' 以写入方式打开文件或创建新文件,在原文件内容后续写新内容 'r+t' 以同时支持读、写方式打开文件 'w+t' 以同时支持读、写方式打开文件或创建新文件,原文件内容会被清除 'a+t' 以同时支持读、写方式打开文件或创建新文件,在原文件内容后续写新内容 'At' 以续写方式打开文件或创建新文件,写入过程中不自动刷新文件内容,适合对磁带介质文件的操作 'Wt' 以写入方式打开文件或创建新文件,原文件内容会被清除,写入过程中不自动刷新文件内容,适合对磁带介质文件的操作 输出值fid是文件标识符(file identifier),它作为其他低级I/O(Input/Output)函数的输入参数。文件打开成功时,fid为正整数,不成功时fid为-1。 2. 调用fcolse函数关闭文件 对fopen函数打开的文件操作结束后,应将其关闭,否则会影响其他操作。fcolse函数用于关闭文件,其调用格式如下: status = fclose(fid) status = fclose('all') 第1种调用用来关闭文件标识符fid指定的文件,第2种调用用来关闭所有被打开的文件。若操作成功,返回status为0,否则为 -1。 3. 调用textscan函数读取数据 textscan函数用来以指定格式从文本文件或字符串中读取数据。它提供了丰富的数据转换格式,能从文件的任何地方开始读取数据,能更好地处理大型数据。其调用格式如下。 (1) C = textscan(fid, 'format')。 输入参数fid为fopen函数返回的文件标识符。format用来指定数据转换格式,它是一个字符串,包含一个或多个转换指示符。返回值C是一个元胞数组,format中包含的转换指示符的个数决定了C中元胞的数目。 转换指示符是由“%”号引导的特殊字符串,基本的转换指示符如表3.23所示。用户还可以在“%”号和指示符之间插入数字,用来指定数据的位数或字符的长度。对于浮点数(%n, %f, %f32, %f64),还可以指定小数点右边的位数。textscan函数支持的字段宽度设置如表3.24所示。 表3.23textscan函数支持的基本转换指示符 字 段 类 型 指示符 说明 有符号整型 %d32位 %d88位 %d1616位 %d3232位 %d6464位 无符号整型 %u32位 %u88位 %u1616位 %u3232位 %u6464位 浮点数 %f64位(双精度) %f3232位(单精度) %f6464位(双精度) %n64位(双精度) 字符串 %s字符串 %q字符串,可能是由双引号括起来的字符串 %c任何单个字符,可以是分隔符 续表 字 段 类 型 指示符 说明 模式匹配字符串 %[…]读取和方括号中字符相匹配的字符,直到首次遇到不匹配的字符或空格时停止。若要包括“]”自身,可用“%[]…]”。例如,%[mus] 会把 'summer ' 读作 'summ' %[^…]读取和方括号中字符不匹配的字符,直到首次遇到匹配的字符或空格时停止。若要排除“]”自身,可用“%[]…]”。例如,%[^xrg] 会把 'summer ' 读作 'summe' 表3.24textscan函数支持的字段宽度设置 指示符说明 %Nc读取N个字符,包括分隔符。例如,%9c 会把 'Let's Go!' 读作 'Let's Go!' %Ns%Nn %Nq%Nd… %N[…]%Nu… %N[^…]%Nf… 读取N个字符或数字(小数点也算一个数字),直到遇到第1个分隔符,不论是什么分隔符。 例如,%5f32 会把 '473.238' 读作 473.2 %N.Dn %N.Df… 读取N个数字(小数点也算一个数字),直到遇到第1个分隔符,不论是什么分隔符。返回的数字有D位小数。例如,%7.2f 会把 '473.238' 读作 473.23 对于每一个数值型转换指示符(例如%f),textscan函数返回一个K×1的数值型向量作为C的一个元胞,这里的K为读取指定文件时该转换指示符被使用的次数。对于每一个字符型转换指示符(例如%s),textscan函数返回一个K×1的字符元胞数组作为C的一个元胞。%Nc会返回一个K×N的字符数组作为C的一个元胞。 通常情况下,textscan函数按照用户设定的转换指示符来读取文件中的相应类型字段的全部内容。用户还可设置需要跳过的字段和部分字段,用来忽略某些类型的字段或字段的一部分,可用的设置如表3.25所示。 表3.25跳过某些字段或部分字段的转换指示符 指示符 说明 %*…跳过某些字段,不生成这些字段的输出。 例如,'%s %*s %s %s %*s %*s %s' 把字符串 'Blackbird singing in the dead of night' 转换成具有4个元胞的输出,元胞中字符串分别为'Blackbird'、'in'、'the'、'night' %*n… 忽略字段中的前n个字符,n为整数,其值小于或等于字段中字符个数。例如,%*4s 把'summer '读作'er' 指定字符 忽略字段中指定的字符。例如,Level%u8 把 'Level1' 读作1,或者%u8Step把'2Step'读作2 (2) C = textscan(fid, 'format', N)。 重复使用N次由format指定的转换指示符,从文件中读取数据。fid和format的说明同上。N为整数,当N为正整数时,表示重复次数,当N为-1时,表示读取全部文件。 (3) C = textscan(fid, 'format', param, value, …)。 利用可选的成对出现的参数名与参数值来控制读取文件的方式。fid和format的说明同上。字符串param用来指定参数名,value用来指定参数的取值。可用的参数名与参数值如表3.26所示。 表3.26textscan函数支持的参数名与参数值列表 参数名 参数值(设定值) 默认值 BufSize 最大字符串长度,单位是byte 4095 CollectOutput 取值为整数,若不等于0(即为真),则将具有相同数据类型的连续元胞连接成一个数组 0(假) CommentStyle 忽略文本内容的标识符号,可以是单个字符串(如'%'),也可以是由两个字符串构成的元胞数组(如{'/*', '*/'})。若为单个字符串,则该字符串后面的在同一行上的内容会被忽略。若为元胞数组,则两个字符串中间的内容会被忽略 无 Delimiter 分隔符 空格 EmptyValue 空缺数字字段的填补值 NaN EndOfLine 行结尾符号 从文件中识别: \n, \r, or \r\n ExpChars 指数标记字符 'eEdD' HeaderLines 跳过的行数(包括剩余的当前行) 0 MultipleDelimsAsOne 取值为整数,若不等于0(即为真),则将连在一起的分隔符作为一个单一的分隔符。只有设定了delimiter选项,它才是有效的 0(假) ReturnOnError 取值为整数,用来确定读取或转换失败时的行为。若非0(即为真),则直接退出,不返回错误信息,输出读取的字段。若为0(即为假),则退出并返回错误信息,此时没有输出 1(真) TreatAsEmpty 在数据文件中被作为空值的字符串,可以是单个字符串或字符串元胞数组。只能用于数字字段 无 Whitespace 作为空格的字符 ' \b\t' (4) C = textscan(fid, 'format', N, param, value, …)。 结合了第2种和第3种调用格式,可以同时设定读取格式的重复使用次数和某些特定的参数。 (5) C = textscan(str, …)。 从字符串str中读取数据。第1个输入参数str是普通字符串,不再是文件标识符,除此之外,其余参数的用法与读取文本文件时相同。 (6) [C, position] = textscan(…)。 读取文件或字符串中的数据C,并返回扫描到的最后位置position。若读取的是文件,position就是读取结束后文件指针的当前位置,等于ftell(fid)的返回值。若读取的是字符串,position就是已经扫描过的字符的个数。 【例3.22】TXT文件“体测成绩数据.txt”中包含以下内容: 序号身高体重肺活量肥胖程度 1168.474.24686肥胖 2162.350.33275较低体重 3177.163.83867正常体重 4169.848.73327营养不良 517471.52805超重 6161.952.13625较低体重 7178.353.83678营养不良 8159.955.23007正常体重 9162.157.72800正常体重 10171.272.21609肥胖 调用textscan函数读取该文件的MATLAB命令如下: >> fid = fopen('体测成绩数据.txt');% 打开数据文件,返回文件标识符 % 按指定格式读取数据,并将相同类型的连续列进行合并 >> data1 = textscan(fid,'%d %f %f %d %s','HeaderLines',1,'CollectOutput',1) data1 = [10x1 int32][10x2 double][10x1 int32]{10x1 cell} >> data1{2} % 查看读到的数据 ans = 168.400074.2000 162.300050.3000 177.100063.8000 169.800048.7000 174.000071.5000 161.900052.1000 178.300053.8000 159.900055.2000 162.100057.7000 171.200072.2000 >> fclose(fid);% 关闭文件 上述命令中的数据转换格式为'%d %f %f %d %s',textscan函数将第1和第4列数据读为32位整型数据,将第2和第3列数据读为64位双精度浮点型数据,将第5列读为字符型数据。读到的数据保存在元胞数组data1中。通过设置CollectOutput参数值为1,可将读取到的具有相同数据类型的连续列(第2和第3列)合并输出。 【例3.23】TXT文件“教师信息数据.txt”中包含以下内容: Name: xiezh Age: 18 Height: 170 Weight: 65 kg Name: molih Age: 16 Height: 160 Weight: 52 kg Name: liaoj Age: 15 Height: 160 Weight: 50 kg Name: lijun Age: 20 Height: 175 Weight: 70 kg Name: xiagk Age: 15 Height: 172 Weight: 56 kg 调用textscan函数可以非常灵活地读取这种文字与数据交替出现的数据文件,参见下面的MATLAB命令。 >> fid = fopen('教师信息数据.txt','r');% 以只读方式打开文件:教师信息数据.txt % 调用textscan函数以指定格式从文件中读取数据,用空格(' ')作分隔符,并将相同类型的列合并 >> A = textscan(fid, '%*s %s %*s %d %*s %d %*s %d %*s',... 'delimiter', ' ', 'CollectOutput',1) A = {5x1 cell}[5x3 int32] >> A{1,1}% 查看A的第1行、第1列的元胞中的数据 ans = 'xiezh' 'molih' 'liaoj' 'lijun' 'xiagk' >> A{1,2}% 查看A的第1行、第2列的元胞中的数据 ans = 18170 65 16160 52 15160 50 20175 70 15172 56 >> fclose(fid);% 关闭文件 3.2.3调用fgetl和sscanf函数读取TXT数据文件 fgetl函数用来读取文件中的一行内容,并删除换行符。sscanf函数用来从字符串中读取格式化数据。将fgetl和sscanf函数配合使用,可从TXT数据文件中逐行读取数据。 【例3.24】调用fgetl和sscanf函数逐行读取TXT文件“教师信息数据.txt”中的数值型数据。 >> fid = fopen('教师信息数据.txt','r');% 以只读方式打开文件:教师信息数据.txt >> k = 1; >> while ~feof(fid) % 用while循环逐行读取数据 str = fgetl(fid);% 读取一行内容 % 忽略姓名字符串,读取该行中的整型数据(年龄、身高和体重) data(k,:) = sscanf(str,'Name: %*s Age: %d Height: %d Weight: %d kg')'; k = k + 1; end >> fclose(fid); % 关闭文件 >> data% 查看读取的数据 data = 18170 65 16160 52 15160 50 20175 70 15172 56 【说明】feof函数用来判断是否到达文件末尾。调用格式如下: eofstat = feof(fid) 输入参数fid为文件标识符。当到达文件末尾时,输出eofstat = 1,否则eofstat为0。 3.2.4调用xlsread函数读取Excel数据文件 xlsread函数用来读取Excel工作表中的数据。原理是这样的,当用户系统安装有Excel时,MATLAB创建Excel服务器,通过服务器接口读取数据。当用户系统没有安装Excel或MATLAB不能访问COM服务器时,MATLAB利用基本模式(basic mode)读取数据,即把Excel文件作为二进制映像文件读取进来,然后读取其中的数据。xlsread函数的调用格式如下。 (1) num = xlsread(filename)。 读取由filename指定的Excel文件中第1个工作表中的数据,返回一个双精度矩阵num。输入参数filename是由单引号括起来的字符串。 当Excel工作表的顶部或底部有一个或多个非数字行(如图3.13中的第1行),左边或右边有一个或多个非数字列(如图3.13中的第H列)时,在输出中不包括这些行和列。例如,xlsread会忽略一个电子表格顶部的文字说明。 如图3.13中的第D列,它是一个处于内部的列。对于内部的行或列,即使它有部分非数字单元格,甚至全部都是非数字单元格,xlsread也不会忽略这样的行或列。在读取的矩阵num中,非数字单元格位置用NaN代替。 (2) num = xlsread(filename, -1)。 在Excel界面中打开数据文件,允许用户交互式选取要读取的工作表以及工作表中需要导入的数据区域。这种调用会弹出一个提示界面,提示用户选择Excel工作表中的数据区域。在某个工作表上单击并拖动鼠标即可选择数据区域,然后单击提示界面上的“确定”按钮即可导入所选区域的数据。 (3) num = xlsread(filename, sheet)。 用参数sheet指定读取的工作表。sheet可以是单引号括起来的字符串,也可以是正整数。当是字符串时,用来指定工作表的名字; 当是正整数时,用来指定工作表的序号。 (4) num = xlsread(filename, range)。 用参数range指定读取的单元格区域。range是字符串,为了区分sheet和range参数,range参数必须包含冒号,形如 'C1:C2' 的表示区域的字符串。若range参数中没有冒号,xlsread就会把它作为工作表的名字或序号,这有可能导致错误。 (5) num = xlsread(filename, sheet, range)。 同时指定工作表和工作表区域。此时range参数可以是Excel文件中定义的区域的名字。 【例3.25】用xlsread函数读取文件“概率统计成绩.xls”第1个工作表中区域A2:H4 的数据。命令及结果如下: % 读取文件"概率统计成绩.xls"第1个工作表中单元格A2:H4中的数据 % 第一种方式: >> num1 = xlsread('概率统计成绩.xls', 'A2:H4')% 返回读取的数据矩阵num1 num1 = 1601016010101NaN214263 2601016010102NaN254873 3601016010103NaN000 % 第二种方式: >> num2 = xlsread('概率统计成绩.xls', 1, 'A2:H4')% 返回读取的数据矩阵num2 num2 = 1601016010101NaN214263 2601016010102NaN254873 3601016010103NaN 000 % 第三种方式: >> num3 = xlsread('概率统计成绩.xls', 'Sheet1', 'A2:H4')% 返回读取的数据矩阵num3 num3 = 1601016010101NaN214263 2601016010102NaN254873 3601016010103NaN000 (6) num = xlsread(filename, sheet, range, 'basic')。 用基本模式(basic mode)读取数据。当用户系统没有安装Excel时,用这种模式导入数据导入功能会受限,range参数的值会被忽略,可以设定range参数的值为空字符串(''),而sheet参数必须是字符串,此时读取的是整个工作表中的数据。 (7) [num, txt]= xlsread(filename, …)。 返回数字矩阵num和文本数据txt。txt是一个元胞数组,txt中与数字对应位置的元胞为空字符串“''”。例如: >> [num4,text4] = xlsread('概率统计成绩.xls', 'Sheet1', 'A2:H4') num4 = 1601016010101NaN214263 2601016010102NaN254873 3601016010103NaN000 text4 = '陈亮''''''''' '李旭''''''''' '刘鹏飞''''''''缺考' 3.2.5调用readtable函数创建数据表 1.4.9节介绍了用table函数把工作空间中的变量定义为表格型数组,这里介绍用readtable函数读取外部数据文件,创建表格型数组。readtable函数是MATLAB R2013b(8.2)版本才有的函数。 【例3.26】TXT文件“学生信息数据.txt”中包含以下内容: Name,Age,Height,Weight 和平,18,170,65 谢润和,16,160,52 韩宇浩,15,160,50 金志文,20,175,70 邓泽楷,15,172,56 用readtable函数读取该文件中的数据,创建表格型数组。 >> T = readtable('学生信息数据.txt','Delimiter',',','ReadRowNames',true) T = AgeHeightWeight 和平1817065 谢润和1616052 韩宇浩1516050 金志文2017570 邓泽楷1517256 【例3.27】用readtable函数读取文件“概率统计成绩.xls”中的数据,创建表格型数组。 >> T = readtable('概率统计成绩.xls','ReadRowNames',true); % 修改表格中变量名称 >> T.Properties.VariableNames = {'x1','x2','x3','x4','x5','x6','x7'} T = x1x2x3x4x5x6x7 1601016.0101e+06'陈亮'214263'' 2601016.0101e+06'李旭'254873'' 3601016.0101e+06'刘鹏飞' 00 0'缺考' 4601016.0101e+06'任时迁'275582'' 5601016.0101e+06'苏宏宇'265480'' 6601016.0101e+06'王海涛'214970'' …… 3.3把数据写入文件 MATLAB中用于写数据到文件的函数如表3.31所示。 表3.31MATLAB中写数据到文件的常用函数 函数名说明 save将工作空间中的变量写入文件 dlmwrite 按指定格式将数据写入文本文件 fprintf 按指定格式把数据写入文件 xlswrite 把数据写入Excel文件 writetable 把表格数据写入文件 在MATLAB 7.x版本中,选择File菜单下的Save Workspace As选项,在MATLAB 8.x及以后的版本中,单击工作界面上的保存工作区图标 ,均可将MATLAB工作空间里的所有变量导出到MAT文件(扩展名为“.mat”)。下面介绍save和xlswrite函数的用法。 3.3.1调用save函数保存计算结果 save函数用来将工作空间中的变量写入文件,调用格式如表3.32所示。 表3.32save函数的调用格式 调 用 格 式 说明 save(filename)把工作空间中的所有变量数据写入二进制文件(MAT文件) save(filename,variables) 只把变量variables数据写入二进制文件续表 调 用 格 式 说明 save(filename,variables,fmt) 把变量数据写入文件,用字符串fmt指定文件格式,fmt的可用取值如下: '-mat' : 二进制mat文件(默认情形) '-ascii': 8位精度文本文件 '-ascii','-tabs': 以制表符为分隔符的8位精度文本文件 '-ascii','-double': 16位精度文本文件 '-ascii','-double','-tabs': 以制表符为分隔符的16位精度文本文件 save(filename,variables,version) 把变量数据写入二进制文件,用version指定文件版本,其可用字符串包括: '-v7.3','-v7','-v6','-v4' save(filename,variables,'-append') 以续写方式把变量数据写入文件,不会覆盖文件中已有数据 save filename variables 不同于函数调用格式,这是命令行调用格式,也能把变量数据写入文件 表3.32中的输入参数filename为字符串变量,用来指定目标文件的文件名,可以包含路径,若不指定路径,则自动保存到MATLAB当前文件夹。variables为变量名字符串,形如'Var1','Var2', …。 【例3.31】定义多个变量,调用save函数将它们写入二进制文件“SaveDataToFile.mat”。 >> x = 1:3; % 定义向量x >> y = [1 2 3;4 5 6;7 8 9];% 定义矩阵y >> S = struct('Name',{'谢中华','xzh'},'Age',{20,10});% 定义结构体数组S >> ds = dataset('XLSFile','概率统计成绩.xls');% 定义数据集数组ds >> save('SaveDataToFile.mat');% 以函数调用格式保存所有变量 >> save SaveDataToFile.mat;% 以命令行调用格式保存所有变量 >> save('SaveDataToFile1.mat','y','S'); % 以函数调用格式保存变量y和S >> save SaveDataToFile1.matyS % 以命令行调用格式保存变量y和S 对于用save函数保存的数据文件,可用load函数重新加载,例如: >> clear;% 清除工作空间中的所有变量 >> load SaveDataToFile.mat% 重新加载SaveDataToFile.mat中保存的变量数据 3.3.2调用xlswrite函数把数据写入Excel文件 xlswrite函数用来将数据矩阵M写入Excel文件,它有以下7种调用格式: xlswrite(filename, M) xlswrite(filename, M, sheet) xlswrite(filename, M, range) xlswrite(filename, M, sheet, range) status = xlswrite(filename, …) [status, message] = xlswrite(filename, …) xlswrite filename M sheet range 其中前6种为函数调用格式,最后一种为命令行调用格式。参数filename为字符串变量,用来指定文件名和文件路径。若filename指定的文件不存在,则创建一个新文件,文件的扩展名决定了Excel文件的格式。若扩展名为“.xls”,则创建一个Excel 972003下的文件,若扩展名为“.xlsx”“.xlsb”或“.xlsm”,则创建一个Excel 2007格式的文件。 M可以是一个m×n的数值型矩阵或字符型矩阵,也可以是一个m×n的元胞数组,此时每一个元胞只包含一个元素。由于不同版本的Excel所能支持的最大行数和列数是不一样的,所以能写入的最大矩阵的大小取决于Excel的版本。 Sheet用来指定工作表,可以是代表工作表序号的正整数,也可以是代表工作表名称的字符串。需要注意的是,Sheet参数中不能有冒号。若由Sheet指定的工作表不存在,则在所有工作表的后面插入一个新的工作表。若Sheet为正整数,并且大于工作表的总数,则追加多个空的工作表直到工作表的总数等于Sheet。这两种情况都会产生一个警告信息,表明增加了新的工作表。 range用来指定单元格区域。对于xlswrite 函数的第3种调用,range参数必须包含冒号,形如 'C1:C2' 的表示单元格区域的字符串。当同时指定sheet和range参数时(如第4种调用),range可以是形如'A2'的形式。range指定的单元格区域的大小应与M的大小相匹配,若单元格区域超过了M的大小,则多余的单元格用“#N/A”填充,若单元格区域比M的大小还要小,则只写入与单元格区域相匹配的部分数据。 输出status反映了写操作完成的情况,若成功完成,则status等于1(真); 否则,status等于0(假)。只有在指定输出参数的情况下,xlswrite函数才返回status的值。 输出message中包含了写操作过程中的警告和错误信息,它是一个结构体变量,有两个字段: message和identifier。其中message是包含警告和错误信息的字符串,identifier也是字符串,包含了警告和错误信息的标识符。 【例3.32】生成一个10×10的随机数矩阵,将它写入Excel文件“10阶随机数矩阵.xls”的第2个工作表的“D6:M15”区域。 >> x = rand(10);% 生成一个10行10列的随机矩阵 % 把矩阵x写入文件“10阶随机数矩阵.xls”的第2个工作表中的单元格区域D6:M15,并返回操作信息 >> [s,t] = xlswrite('10阶随机数矩阵.xls', x, 2, 'D6:M15') s = 1 t = message: '' identifier: '' 上面返回的操作信息变量s = 1,变量t的message字段为空,说明操作成功,没有出现任何警告,数据被写入文件“10阶随机数矩阵.xls”的指定位置。 【例3.33】定义一个元胞数组,将它写入Excel文件“测试数据.xls”的自命名工作表的指定区域。 >> x = {1,60101,6010101,'陈亮',63,'';2,60101,6010102,'李旭',73,'';3,60101,... 6010103,'刘鹏飞',0,'缺考'}% 定义一个元胞数组 x = [1][60101][6010101]'陈亮'[63]'' [2][60101][6010102]'李旭'[73]'' [3][60101][6010103]'刘鹏飞'[ 0]'缺考' % 把元胞数组x写入文件"测试数据.xls"的指定工作表(xiezhh)中的单元格区域A3:F5 >> xlswrite('测试数据.xls', x, 'xiezhh', 'A3:F5') Warning: Added specified worksheet. > In xlswrite>activate_sheet at 285 In xlswrite>ExecuteWrite at 249 In xlswrite at 207 上面写入数据的操作返回了一个警告信息: “Warning: Added specified worksheet”,说明文件“测试数据.xls”中指定的工作表xiezhh不存在,此时新插入一个名称为xiezhh的工作表。