元胞数组cell
- 1 Matlab中元胞数组cell的操作
- 1.1 数组与元胞数字相互转换:mat2cell、cell2mat
- 1.1.1 mat2cell使用形式
- 实例一:划分数组并以元胞数组形式返回子数组
- 实例二:按行划分数组
- 1.1.2 cell2mat使用形式
- 实例一:将元胞数组转换为数值数组
- 实例二:将struct元胞数组转换为struct数组
- 实例三:将cell数组转换为struct数组
- 1.2 元胞数组与表相互转换:cell2table、table2cell
- 1.2.1 cell2table使用形式
- 实例:将元胞数组按照指定变量名称转换成表
- 1.2.2 table2cell使用形式
- 实例:将表转换为元胞数组
- 1.3 数组转换为相同大小的元胞数组:num2cell
- 1.3.1 num2cell使用形式
- 实例:将数组转换为元胞数组
- 2 C/C++中元胞数组cell的操作(针对mat文件)
- 2.1 相关函数
- 2.1.1 打开mat文件:matOpen
- 2.1.2 读取mat文件的变量:matGetVariable
- 2.1.3 读取元胞中的数据:mxGetCell
- 2.1.4 获取数据阵列中的数据:mxGetData
- 2.1.5 获取数据阵列矩阵的维数:mxGetM、mxGetN
- 2.1.6 创建数据阵列为双浮点数矩阵:mxCreateDoubleMatrix
- 2.1.7 将变量存入数据阵列:mxSetData
- 2.1.8 将数据阵列存入到mat文件中:matPutVariable
- 2.2 基本处理步骤
- 参考
1 Matlab中元胞数组cell的操作
利用reshape
函数创建一个6*4数组:
A = reshape(1:20,5,4)'
注意:
reshape函数在使用过程中需要注意的是创建数组的维度要和原始的数量对应,不然会报一下错误:
1.1 数组与元胞数字相互转换:mat2cell、cell2mat
1.1.1 mat2cell使用形式
C = mat2cell(A,dim1Dist,...,dimNDist)
将数组 A 划分为更小的数组,并在元胞数组 C 中返回它们。向量 dim1Dist,…dimNDist 指定如何划分 A 的行、列和(如果适用)更高维度。C 中较小的数组可以具有不同大小。A 可以包含任何数据类型。C = mat2cell(A,rowDist)
将数组 A 划分为一个 n×1 元胞数组 C,其中 n 等于 rowDist 中元素的数量。
例如,如果 A 是 60×50 数组,则可以将此参数指定为 [10 20 30],[25 25] 来划分 A,如下面的代码和图形所示。C 是元胞数组,其中包含从 A 中拆分出来的六个子数组。
C = mat2cell(A,[10 20 30],[25 25])
实例一:划分数组并以元胞数组形式返回子数组
将 A 划分为四个 2×3子数组。以元胞数组形式返回子数组。
C = mat2cell(A,[2 2],[3 3])
使用 celldisp
函数显示 C 中的子数组。
celldisp(C)
实例二:按行划分数组
划分 A 的行,以使元胞数组包含两个子数组。由于 rowDist 的第一个元素是 2,因此 C 的第一个元胞包含 A 的第一行。rowDist 的第二个元素是 3,因此 C 的下一个元胞包含 A 的接下来的三行。rowDist 的元素总和等于 A 的行数。
rowDist = [1 3];
C = mat2cell(A,rowDist)
同样使用celldisp
函数显示子数组
celldisp(C)
1.1.2 cell2mat使用形式
A = cell2mat(C)
将元胞数组转换为普通数组。元胞数组的元素必须全都包括相同的数据类型,并且生成的数组也是该数据类型。
例如,同一列中的元胞的内容必须具有相同的列数,但不需要具有相同的行数:
实例一:将元胞数组转换为数值数组
将一个元胞数组的六个元胞中的数值数组转换为一个数值数组。
C = {[1 7], [2 3 4],[12];[13 11 ; 12 23], [6 7 8; 10 11 12],[18;24]}
A = cell2mat(C)
实例二:将struct元胞数组转换为struct数组
a.id = [12 3 8];
a.name = 'X';
b.id = [20 22 24];
b.name = 'h';
c = {a,b};
d = cell2mat(c)
c是元胞数组
d是结构体数组
实例三:将cell数组转换为struct数组
n=3;
%% 初始化一个cell数组
c_info=cell(n,1);
id=[12 3 8];name={'x','l','h'};
age=[20 22 24];
for i=1:n;c_info{i}.id=id(i);c_info{i}.name=name{i};c_info{i}.age=age(i);
end
%% 转化代码
cs_info=[c_info{:}]
cs_info为结构体数组:
cs_info(1,1)的值:
cs_info(1,2)的值:
cs_info(1,3)的值:
1.2 元胞数组与表相互转换:cell2table、table2cell
1.2.1 cell2table使用形式
T = cell2table(C)
将 m×n 元胞数组 C 的内容转换为 m×n 表 T。C 的每一列提供 T 的一个变量中包含的数据。T = cell2table(C,Name,Value)
通过由一个或多个 Name,Value 对组参数指定的其他选项基于元胞数组 C 创建表。
实例:将元胞数组按照指定变量名称转换成表
首先创建一个包含字符向量和数值数据的元胞数组C:
C = {1 'matlab' 2 'A'; 2 'python' 3 'A+';...3 'C++' 4 'A++'; 5 'java' 6 'A-'}
然后将元胞数组 C 转换按照指定变量名称转换成表。
T = cell2table(C,'VariableNames',{'id1' 'course' 'id2' 'grade'})
特别需要注意的是:将元胞数组转成表只能在matlab 2015版本以上,低于2013的没有
cell2table
这个函数
博主的matlab是R2013a的,所以在应用cell2table
时报一下错误:
意思就是:未定义函数’cell2table’作为类型为’cell’的输入参数。
正常运行结果:
T=4×4 tableid1 course id2 grade___ ____________ ________ ______________1 {'matlab' } 2 {'A'} 2 {'python' } 3 {'A+'} 3 {'C++' } 4 {'A++'} 5 {'java'} 6 {'A-' }
1.2.2 table2cell使用形式
C = table2cell(T)
将表 T 转换为元胞数组 C。T 中的每个变量都会成为 C 中的元胞列。
实例:将表转换为元胞数组
创建一个表 T:
T = table(categorical({'M';'M';'F';'F';'F'}),[22;24;21;20;23],...[119 95;121 78; 125 86; 120 85; 122 90],...'VariableNames',{'Gender' 'Age' 'BloodPressure'},...'RowNames',{'Smith' 'Johnson' 'Williams' 'Jones' 'Brown'})
将 T 转换为元胞数组。
C = table2cell(T)
C=5×3 cell array{[M]} {[22]} {1x2 double}{[M]} {[24]} {1x2 double}{[F]} {[21]} {1x2 double}{[F]} {[20]} {1x2 double}{[F]} {[23]} {1x2 double}
1.3 数组转换为相同大小的元胞数组:num2cell
1.3.1 num2cell使用形式
C = num2cell(A)
通过将 A 的每个元素放置于 C 的一个单独元胞中,来将数组 A 转换为元胞数组 C。C = num2cell(A,dim)
将 A 的内容划分成 C 中单独的元胞,其中 dim 指定每个元胞包含 A 的哪个维度。dim 可以是维度的标量或向量。
当dim=1,2,[1 2]时:
num2cell(A,1)
创建一个 1×3 元胞数组 C,其中每个元胞包含 A 的 2×1 列。
num2cell(A,2)
创建一个 2×1 元胞数组 C,其中每个元胞包含 A 的 1×3 行。
num2cell(A,[1 2])
创建一个 1×1 元胞数组 C,其中每个元胞包含 A 整个数组。
实例:将数组转换为元胞数组
利用magic函数创建4*4的数值:
a = magic(4)
将其转化为元胞数组:
c = num2cell(a)
2 C/C++中元胞数组cell的操作(针对mat文件)
注意,针对mat文件操作之前需要加载头文件:#include "mat.h"
2.1 相关函数
2.1.1 打开mat文件:matOpen
MATFile *matOpen(const char *filename,const char *mode)
输入的mode有一下几种形式:
r
:以只读方式打开u
:更新模式,可读可写,但是如果要打开的数据文件不存在,也不会创建新的文件w
:以写入方式打开,只能写入,如果要打开的数据文件不存在,则创建一个新的文件
2.1.2 读取mat文件的变量:matGetVariable
mxArray * matGetVariable(MATFile * pMF, const char * name);
读取名为name的变量,返回一个数据阵列指针
2.1.3 读取元胞中的数据:mxGetCell
C/C++中也有一个针对mat数据中的cell操作函数:
EXTERN_C mxArray *mxGetCell(const mxArray *pa, mwIndex i);
输入:
pa
:指向mxArray类型的指针;i
:元胞中元素的标号;按列优先。
输出:
- 指向mxArray类型的指针。
2.1.4 获取数据阵列中的数据:mxGetData
void *mxGetData(const mxArray *pa );
返回时需要使用强制类型转换。
2.1.5 获取数据阵列矩阵的维数:mxGetM、mxGetN
size_t mxGetM(const mxArray *pa);// 获取矩阵pa的行数
size_t mxGetN(const mxArray *pa);//获取矩阵pa的列数
2.1.6 创建数据阵列为双浮点数矩阵:mxCreateDoubleMatrix
mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexity flag);
2.1.7 将变量存入数据阵列:mxSetData
void mxSetData( mxArray *pa, void *newdata );
2.1.8 将数据阵列存入到mat文件中:matPutVariable
int matPutVariable(MATFile * pMF, const char * name, const mxArray * pA);
存入成功返回0,存入出错返回非0
2.2 基本处理步骤
变量定义及初始化
MATFile *pmat; //指向mat文件的指针const char **dir; //元素名列表const char *file; //mat文件名int ndir; //mat文件中的元素(矩阵、元胞)个数mxArray *cell1; //指向要读取的元胞数据的指针mxArray *mat1; //指向元胞中某个元素的指针double *a; //指向元胞中某个元素第一个数据的指针
首先打开mat文件
pmatFile= matOpen("data.mat", "r");//打开文件,返回指向mat数据指针if (pmatFile == NULL){printf("打开mat文件失败!");return 0;}
然后读取mat文件中的矩阵列表(返回mat中包含的元素的名字)
dir = (const char **)matGetDir(pmatFile, &ndir);if (dir == NULL){printf("读取mat文件失败!");return 0;}
接着,从打开的mat文件中读取名字为dir[0]的元胞,返回指向该矩阵的指针
注意:MATLAB中的矩阵是按列优先存储
cell1 = matGetVariable(pmatFile,dir[0]);//指向名字为dir[0]的元胞
再获取元胞的行数和列数
int cellM = (int)mxGetM(cell1);//获取元胞的行数
int cellN = (int)mxGetN(cell1);//获取元胞的列数
最后按列有限依次读取元胞中的数据
for(int count=0;count<cellM*cellM;count++){mat1 = mxGetCell(cell1,count);//按列优先,指向元胞中的第count+1个元素a = (double*)mxGetData(mat1);//指向mat1中的第一个数据M = (int)mxGetM(mat1);//获取mat1的行数N = (int)mxGetN(mat1);//获取mat1的列数printf("元素%d的维数为:(%d,%d)\n",count,M,N);for (int i=0;i<M;i++){for (int j=0;j<N;j++)printf("%f ",a[j*M+i]);printf("\n");}}
参考
- https://ww2.mathworks.cn/help/matlab/ref/struct2cell.html
- https://blog.csdn.net/jnulzl/article/details/49623121
- https://blog.csdn.net/left_la/article/details/8206645
要不先来个一键三连,以表谢意