转载地址:http://www.matlabsky.com/forum.php?mod=viewthread&tid=21089
从celll使用说起
在读取文件的时候,cell数组(各种翻译都有,元胞数组,单元数组...直接无视)是MATLAB的宠儿,基本都会出现,长期使用发现频率比struct高不少~无论是Import Data还是使用textscan之类获取数据,从长期使用高级语言的角度来说,特别是习惯了面向对象之后更习惯使用struct数组,概念也很相似,奈何现实是...我们先看一下Matlab在help给出的定义:
“A cell array is a collection of containers callled cells in which you can store different types of data”
精华之处就是可以存储不同类型的数据,可以是Matlab的类型或者自定义的类型
cell数组的一些操作
创建:直接使用{}以及cell(...)形式,另外下标法赋值也可以,注意后两种可以预配内存,内存是空间连续的~
读取内容:{下标}和(下标)区别类型()是cell数组,{}是实际类型,结果显示是一致的
>> a={'啊',123,[3 5 6],[1 2;7 8],sym(1)}
a =
'啊' [123] [1x3 double] [2x2 double] [1x1 sym]
>> class(a{1})
ans =
char
>> class(a(1))
ans =
cell
>>
C{5,3}{4,7}(:,4)
解读: cell数组的一个元素为cell类型,包含一个普通矩阵类型
x = C{5,3}; % x is a cell array
y = x{4,7}; % y is also a cell array
z = y(:,4) % z is a standard array
调整内容:添加和删除与普通矩阵方法一致
相关函数:
celldisp:显示所有的内容
cell:创建空的元胞数组
cellplot:利用图像方式显示内容
cell2mat:将数组转变成普通的矩阵
mat2cell:将数值矩阵转变成cell数组
num2cell:将数值数组转变成cell数组
cell2struct:将数组转变成为结构
struct2cell:将结构转变成cell数组
iscell:判断输入是否为cell数组
cellfun:为cell数组的每个cell执行指定的函数,fun可以使特殊的函数或者句柄
days{1} = 'Sunday'; days{2} = 'Monday';
days{3} = 'Tuesday'; days{4} = 'Wednesday';
days{5} = 'Thursday'; days{6} = 'Friday';
days{7} = 'Saturday';
shortNames = cellfun(@(x)x(1:3), days, 'UniformOutput', false)
shortNames =
'Sun' 'Mon' 'Tue' 'Wed' 'Thu' 'Fri' 'Sat'
cell数组的类型转换
Cell Array and Struct Array
s = cell2struct(c,fields,dim) cell数组转换为struct数组,注意fields为char数组或者cell数组,而且size(c,dim) == length(fields)
%If fields is a cell array size(c,dim)==size(fields,1) %If fields is a char array 这个经常错误就是fields类型以及dim不对
c = struct2cell(s) struct数组转换为cell数组 这个基本上没有什么错误
Matrix and Cell Array
c = mat2cell(x,m,n) 转换为m行n列cell数组 m = cell2mat(c) 必须为同一类型,而且限制不可包含cell数组或object类型,但是
struct结构是可以的(同样这个struct不含cell和object类型,否则依旧出错)
Double and Cell Array
C = num2cell(A, [dim1, dim2, ...]) 返回C的维数是numel(A)/prod(X,Y,...) dimN 是一个整数,范围是1到ndims(A)
只有数值矩阵才可以直接转换为cell,没有供cell转为double的方法.这是非常让人恼火的!不过理解之后就知道,cell本来就是混 合类型的,直接转向数值类型单一矩阵,这样是不合理的.通常如果是的确是数值类型的可以走以下路线:cell->cell2mat 这时候 注意cell2mat的条件非cell和object.否则,循环或者cellfun处理.如果可以使用 cell2mat 或者cat(dim,c{:}).很多时候都很方便
Cell Arrays Of Strings
单独列出了是因为很多时候都要接触这个,基本txt之类读取来的数值数据都是char的cell数组~
可以使用cell参数与字符有关的部分函数(基本都支持)
cellstr Convert a character array to a cell array of strings.会去除末尾空白
char Convert a cell array of strings to a character array. 会恢复转换时候失去的空白
deblank Remove trailing blanks from a string.
iscellstr Return true for acell array of strings.
sort 排序.
strcat 连接字符.
strcmp 对比字符.
strmatch 查找字符.
strrep 替换字符
regexp系列及accumarray支持行列向量
读写
数据读取进来了,处理后是需要保存的,可是面对要求你总是很无奈,要是可以.mat格式那个很好啊,可是大部分要求都是txt之类的。(不明白为什么呢 其实数据库之类Matlab也是支持的...哎,需求总是最后的注脚...)首先要了解怎么情况会有cell数组产生:具体
查看textscan的说明。大文件的读取首先推荐这个函数,处理灵活可以省去很多功夫,具体的格式设置很关键!能够有效分离cell数据的结果方便处理~否则3000万个数据循环绝对是out of memory...尽量使用高级的IO读写...另外,7.0很多读取都是数值返回cell的char类型数组 7.6以上都是用double了,包括xlsread...
如果允许,xlswrite是最好的选择~大量数据测试的结果还是非常好的
在Matlab帮助里面的循环例子:
mycell = { 'a' 1 2 3 ; 'b' 4 5 6 };
[nrows,ncols]= size(mycell);
filename = 'celldata.dat';
fid = fopen(filename, 'w');
for row=1:nrows
fprintf(fid, '%s %d %d %d\n', mycell{row,:});
end
fclose(fid);
仅有数值的时候,可以考虑先cell2mat,然后csvwrite.
cellfun的例子可以参考Matlab公司的http://www.mathworks.cn/support/solutions/en/data/1-1190ZB/index.html?solution=1-1190ZB
总结
基本是就是总结了一下用法,特别是转换和保存方面的,相对于struct数组,由于Matlab中支持甚多,因此也就常用了.功能偏弱,但是基本按照规则,还是可以尽量减少出错的.
希望大家也交换一下使用的心得~
成功ff