matlab无法从double转换成cell_【MATLAB】cell、double、string 数组间的型态转换

夏恩觉得在 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

其实转换的函数也就这么几个,用习惯了就不会搞混了。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Qt中使用matlab库对mat文件进行读写操作,需要使用Matlab Engine API。以下是一个示例代码,演示了如何读取和写入一个包含cell类型的mat文件: ```cpp #include <QCoreApplication> #include <engine.h> #include <iostream> #include <string> #include <vector> #include <mat.h> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // Start a MATLAB engine Engine *ep = engOpen(nullptr); if (!ep) { std::cerr << "Failed to open MATLAB engine" << std::endl; return 1; } // Load the mat file MATFile *pmat = matOpen("example.mat", "r"); if (!pmat) { std::cerr << "Failed to open mat file" << std::endl; return 1; } // Get the variable from the mat file mxArray *pa = matGetVariable(pmat, "cellVar"); if (!pa) { std::cerr << "Failed to get variable from mat file" << std::endl; return 1; } // Get the data from the mxArray int nRows = mxGetM(pa); int nCols = mxGetN(pa); std::vector<std::vector<double>> data(nRows, std::vector<double>(nCols)); for (int i = 0; i < nRows; ++i) { for (int j = 0; j < nCols; ++j) { mxArray *elem = mxGetCell(pa, i + nRows*j); data[i][j] = mxGetScalar(elem); } } // Close the mat file matClose(pmat); // Do something with the data std::cout << "Read data from mat file:" << std::endl; for (int i = 0; i < nRows; ++i) { for (int j = 0; j < nCols; ++j) { std::cout << data[i][j] << " "; } std::cout << std::endl; } // Write data to a new mat file MATFile *pmatNew = matOpen("exampleNew.mat", "w"); if (!pmatNew) { std::cerr << "Failed to create new mat file" << std::endl; return 1; } mxArray *paNew = mxCreateNumericMatrix(nRows, nCols, mxDOUBLE_CLASS, mxREAL); for (int i = 0; i < nRows; ++i) { for (int j = 0; j < nCols; ++j) { mxArray *elem = mxCreateDoubleScalar(data[i][j]); mxSetCell(paNew, i + nRows*j, elem); } } matPutVariable(pmatNew, "cellVarNew", paNew); // Close the new mat file matClose(pmatNew); // Close the MATLAB engine engClose(ep); return 0; } ``` 在此示例中,我们打开了一个名为 `example.mat` 的mat文件,并从中获取了名为 `cellVar` 的变量。这个变量包含了一个 `nRows` 行 `nCols` 列的cell数组,其中每个元素都是一个double类型的数值。我们将数据存储在一个 `std::vector<std::vector<double>>` 中,并打印出来。然后,我们将这个数据写入一个新的mat文件 `exampleNew.mat` 中,其中变量名为 `cellVarNew`。 需要注意的是,这个示例代码假设了mat文件中包含了一个名为 `cellVar` 的变量,并且这个变量是一个 `nRows` 行 `nCols` 列的cell数组,其中每个元素都是一个double类型的数值。如果你的mat文件中包含了其他类型的变量,或者变量的尺寸和类型与上述描述不同,你需要根据实际情况进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值