夏恩觉得在 MATLAB 内的数据型态中,最好用的就是细胞数组。
最头疼的呢,也是细胞数组。
就如同 python 的 List 型态,我们可以放心地放入任何数据,不会受到任何制裁。
好用的前提是,我们得先明白在不同数据格式间的转换方法。
版本资讯:
Matlab版本:R2017b (核心即可,不用多余的工具箱)
重点整理:
先讲结论:
会用 cellfun 的话,请直接使用之,用法附在最后面;
若不会,则下面提供几个方法供您参考:
1.在 cell array 中,把文字转数字:
string() 或 char() > str2double() > num2cell()
拆cell > 转换型态 > 回cell
2.在 cell array 中,数字转文字:
cell2mat() > string() 或 char() > cellstr()
拆cell > 转换型态 > 回cell
其中 mat2cell 颜色不一样表示使用方法较特殊,须小心使用。
以下都是关于这张表所提到之函数的详细说明。
一、获得一份数据:
夏恩先制作一份虚拟的订单数据,供大家参考。
有需要的请自行复制贴上即可。ordermachinequantity
S3-732A484
S3-676A638
L3-744A638
L3-745B638
L3-880B504
R2-719B282
R3-741B282
R3-755C580
L1-550D357
L1-611E336
SD-019E251
SD-123E501
SD-144E1153
这份表格的字段依序是订单编号(字符串)、机台编号(字符串)、订单数量(整数)。
文件名称为 test,格式为 xlsx 文件。
首先我们先使用 readtable 把文件读进来,示范如下:
这边补充一点就是字段名称最好使用英文,若使用中文字段名称,
其字段数据会呈现默认的 x_??? 格式,而实际数据则会存放到 Properties.VariableDescriptions 属性中。
以下示范使用中文字段名称会发生什么事情:
为了要找到正确的字段名称,还真花了本恩不少时间。
所以为了省事,还是乖乖地用英文字段名称吧!
table 格式非常好用,使用者可以直接结合两份表格数据,使用 innerjoin 或是 outerjoin 都可以,
不过这不是本文的重点,所以改天再聊。
二、转 table 为 cell:
使用 table2cell 即可满足需求,程序太短不额外打字,如图。
其实 table 有三种转换方法,分别为:table2cell、table2struct、table2array。
其中,table2array 的限制比较多,少用。
又 cell 型态比 struct 好用,所以夏恩最常用的语法就是 table2cell 啦!
三、int(double) cell 与 array 间的转换:
现在来了一个情境题,那就是我们希望加总所有的订单数据。
如果直接使用 sum 命令,会报错,如图:
这边需要先使用 cell2mat 做转换后,才能做加总的动作,其他矩阵操作亦然。
操作完毕,现在我们想要把算好的数据放到原始数据的第四个字段,
这里使用 num2cell 转换回去。
很多时候我们习惯直接打 mat2cell 来做转换,通常会报错。
mat2cell 的用法较为复杂,是专门设计来切分不同大小的 cell array 。
例如:
在这个范例中,mat2cell 可以允许使用者将原始的数组以不同大小切开,分别放到 cell array 内。
若将上面范例中的 num2cell 改成 mat2cell 的话,写法需改成:
newcol = mat2cell(trans .* 2, ones(length(trans), 1))
范例如下图:
四、string(char) cell 与 array 间的转换
下一个情境题,夏恩想要把每一笔订单后面通通加上一个数字,
和刚刚一样,cell 不能够直接做数组操作,因此需要经过转换才可以。
把 cell array 拆开成 char or string array 的方法就是直接调用 char() 或 string() 就可以了。
反过来,若要把 char or string array 转换成 cell array 的话,请使用 cellstr() 函数。
欸,等等...
使用 char() 或 string() 结果都一样,那为什么要分不同的函数勒?
别急。这个问题下一个部分会回答,先别管那么多,看范例就是了。
string(char) cell 与 array 间的转换,范例如下:
五、数字与文字间的转换
数字转文字,文字转数字,这大概是最常见的问题了。
在一般的数组中,我们可以直接使用 int2str 或 str2double ...等直接转换整个数组。
但是在 cell 中不允许这种操作,需要在中间加一层 cell2mat 之类的转换函数才行。
在这个部分,夏恩也同时要介绍 char() 和 string() 在使用上的差异性。
再次出现情境题:夏恩想要把订单数量改成文字格式,而非原本的数字格式,何解?
以下示范转成 char 和转成 string 的差别:
为了避免让数据愈来愈乱,夏恩先把数据重新载入一遍,再来看两者的差别。
看到红线标起来的地方了吗
眼尖的人可以发现:天啊!使用 char array 会多一个空格欸!!!!!
是的,这就是差别。
这个差别非常致命,尤其在进行字符串比较的时候。
以上面红线为例,程序执行字符串比对时,' 968' 不等于 '968',因为多了个空白。
但实际上他们是一样的东西!
这边的重点绝对不是在强调谁好谁坏,每种数据格式都有其优缺点。
身为使用者的我们,责任就是了解每种数据格式的特性,并且挑选最符合需求的格式来用。
好的,处理完文字转换后,再使用 cellstr 转 string 为 cell。
最后,将整个字段放到最后面,范例如下:
到这边,我们已经成功地将数字转换成文字了。
接着,再把刚才生出来的那一串文字转成数字吧。
有没有更简单的写法?
答案是...有的。
使用 cellfun 来帮助我们转换吧!
% 数字转字符串
trans = cellfun(@num2str, data, 'UniformOutput', false);
% 字符串转数字
trans = cellfun(@str2double, data, 'UniformOutput', false);
一句话搞定。
小结
最后,再来复习一次,
也就是放在最前面的结论。
会用 cellfun 的话,请直接使用之;
若不会,则上述提供几个方法供您参考:
1.在 cell array 中,把文字转数字:
string() 或 char() > str2double() > num2cell()
拆cell > 转换型态 > 回cell
2.在 cell array 中,数字转文字:
cell2mat() > string() 或 char() > cellstr()
拆cell > 转换型态 > 回cell
其实转换的函数也就这么几个,用习惯了就不会搞混了。