|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
% ^) O8 \# a" D) I0 g. S由于工作需要,经常要处理大量的实验数据.基本都是由仪器导出来,随着社会发展的进步,人们获取数据的量在不断增长,很多人都是,现在已经是海量数据时代了...- }5 i+ w9 [9 k* ^" J/ `7 E5 B
从cell使用说起 8 J4 M1 p$ ?' z, q
在读取文件的时候,cell数组(各种翻译都有,元胞数组,单元数组...直接无视)是MATLAB的宠儿,基本都会出现,长期使用发现频率比struct高了不少~无论是Import Data还是使用textscan之类来获取数据.从长期使用高级语言的角度来说,特别是习惯了面向对象之后i,更习惯使用struct数组,概念也很相似,奈何现实是...我们先看一下Matlab在help给出的定义:
4 r5 r( i* b# b+ pA cell array is a collection of containers called cells in which you can store different types of data.) j9 \; [. }- ~. Q; I% j
* B7 {* {3 w# H5 \$ O精华之处就是在可以存储不同类型的数据.可以是Matlab的类型或者自定义的类型./ v# {4 i( N1 n8 E
cell数组的一些操作2 a. M W4 M+ T" t( o
创建:直接使用{}以及cell(...)形式,另外 下标法赋值也可以.注意后两种可以预配内存,内存是空间连续的~
2 ~% ?5 C+ |9 @. _7 V读取内容:{下标}和(下标) 区别在于类型()是cell数组 ,{}是实际类型.结果显示是一致的" h# ?5 D5 m& {. K. l4 f
>> a={'啊',123,[3 5 6],[1 2;7 8],sym(1)}1 @2 Z# a* `: H; r R% e
a =
6 ^0 Z7 k2 b7 q' f3 [- s '啊' [123] [1x3 double] [2x2 double] [1x1 sym]
+ k. x/ v5 u4 S6 z0 }>> class(a{1})
8 A' x7 w+ s' t A8 q# Z3 uans =9 D, |6 g1 ~9 ?8 w
char
: E9 `' w3 b Y6 L$ g" R, U>> class(a(1))
- e$ i9 O( ^6 Z! z' I5 b2 sans =4 n; G& w/ | k6 n0 O
cell/ ]4 n3 I3 n; ~. C, ^
>>
G8 C6 P- C; c' N3 R* XC{5,3}{4,7}(:,4) H0 l8 J8 o, ?6 v) X5 C+ I; K
解读: cell数组的一个元素为cell类型,包含一个普通矩阵类型( S; }( ?! E' u( }! B$ s
x = C{5,3}; % x is a cell array
6 `$ B& D. b- \! @+ w9 ?( Oy = x{4,7}; % y is also a cell array
6 ?: u# f% f+ `3 w0 i+ dz = y(:,4) % z is a standard array
, o& u. G3 m! Q# g1 H4 J) S% Z3 b复制代码
; W/ w& Y7 v; B! s# U+ @调整内容:添加和删除与普通矩阵方法一致" l8 P0 j5 E5 U" d% i
相关函数:% W- S& t) `% F1 Q5 L
celldisp:显示所有的内容% x9 ~ H9 I5 Z& ~
cell:创建空的元胞数组
& z1 y$ E" c+ v& o+ n cellplot:利用图形方式显示内容" }6 ?% c& A9 M+ L' |% p
cell2mat:将数组转变成为普通的矩阵
7 l+ @ S2 _; \$ \" ? mat2cell:将数值矩阵转变成为cell数组
- H; v) I2 z4 l/ x num2cell:将数值数组转变成为cell数组, L5 x2 U6 }, S2 e! S7 o/ v
cell2struct:将数组转变成为结构 M7 r( A' a( `7 E* r) j. Q M
struct2cell:将结构转变为cell数组) x! ~) V/ |. \# N+ b
iscell:判断输入是否为cell数组2 M5 B+ J& T0 i
cellfun:为cell数组的每个cell执行指定的函数 fun可以是特殊函数或者句柄* W Y6 Y% @% k; e! O B) Z
days{1} = 'Sunday'; days{2} = 'Monday';
: d0 v) U- R) F, {days{3} = 'TuESDay'; days{4} = 'Wednesday';6 @/ o5 W( C6 n4 `" w2 b
days{5} = 'Thursday'; days{6} = 'Friday';
: _! i2 r( Z2 ]8 |( F W$ U5 B2 ~days{7} = 'Saturday';) {" B" s* m- L( v6 {
4 Z/ ~/ m* b" U" C; h& y) w RshortNames = cellfun(@(x)x(1:3), days, 'UniformOutput', false)+ r# V5 ?+ k$ f+ d% H+ \
shortNames =
- B% g F P5 i v 'Sun' 'Mon' 'Tue' 'Wed' 'Thu' 'Fri' 'Sat'
1 H5 H7 C9 N2 _; s8 j' {" S复制代码
/ e& W5 [) {5 D deal:将输入参数赋值给输出 [Y1, Y2, Y3, ...] = deal(X{:}) ->可以简化[a,b,c,d] = C{:}8 u! C6 e2 B% u8 D- m
cell数组的类型转换看到上面的那些类型转换函数,也许你会笑了,感觉也没有什么特别的,但是使用过这个cell数组的朋友,估计大部分都会有转换失败的经历-_-很坑爹的...
9 Y* S! d9 A9 _3 v* i P2 T- A/ M7 G4 ^7 i8 G8 {/ D4 g* h8 ]
Cell Array and Struct Array2 U+ B; X. [9 I" q9 A: H
s = cell2struct(c, fields, dim) cell数组转换为struct数组,注意fields为char数组或者cell数组,而且size(c,dim) == length(fields) % If fields is a cell arraysize(c,dim) == size(fields,1) % If fields is a char array 这个经常错误就是fields类型以及dim不对
# x8 n4 _8 j! u4 N c = struct2cell(s) struct数组转换为cell数组 这个基本没有什么错误的
! @# u$ c j9 ], s3 _) W
! i1 v# e$ f E1 c0 mMatrix and Cell Array
- `4 T& a$ b7 j6 Q5 Y* F& Bc = mat2cell(x, m, n) 转换为 m行n列cell数组 m = cell2mat(c) 必须是同一类型,而且限制不可包含cell数组或object类型,但是struct结构是可以的(同样这个struct不含 cell和object类型,否则依旧出错). D) @& S4 d! `$ ?6 S! J
* E2 A/ e; I* x5 j
Double and Cell Array8 B# w4 m( k. N$ a7 _
C = num2cell(A, [dim1, dim2, ...]) 返回C的维数是numel(A)/prod(X,Y,...) dimN 是一个整数,范围是1到ndims(A)
% @$ k/ k, K3 l: q0 f6 b6 I% o只有数值矩阵才可以直接转换为cell,没有供cell转为double的方法.这是非常让人恼火的!不过理解之后就知道,cell本来就是混合类型的,直接转向数值类型单一矩阵,这样是不合理的.通常如果是的确是数值类型的可以走以下路线:cell->cell2mat 这时候注意cell2mat的条件非cell和object.否则,循环或者cellfun处理.如果可以使用 cell2mat 或者cat(dim,c{:}).很多时候都很方便( ? O, ^+ E9 W D' o6 l1 D- V
Cell Arrays of Strings / b0 ^0 v8 `! A
单独列出了是因为很多时候都要接触这个,基本txt之类读取来的数值数据都是char的cell数组~
6 w8 W5 I; ?9 d9 d可以使用cell参数与字符有关的部分函数(基本都支持)$ R5 z; @9 o. a2 [# @! _% b/ A
cellstr Convert a character array to a cell array of strings.会去除末尾空白0 o6 S! H: j( s P1 ~
char Convert a cell array of strings to a character array. 会恢复转换时候失去的空白( }3 T! N- F3 K3 v8 Z6 F
deblank Remove trailing blanks from a string./ m: ~2 P8 Z( h) ?" k% g, g
iscellstr Return true for acell array of strings.
T2 ]( w* S2 Rsort 排序.
/ S( J+ r8 a5 L/ jstrcat连接字符.; s% x7 L5 q- j( ?, N: p
strcmp对比字符.
! j1 [* [/ a8 ~, \1 kstrmatch 查找字符.) u. r2 @( k5 ~
strrep 替换字符
3 ` W" L8 R ]: p! \5 Kregexp系列及accumarray支持行列向量.; ?) U$ N0 e# n, T# z
' i3 N \4 ~: a7 d
读写
0 S# M' |( Z+ T数据读取进来了,处理后当然是需要保存的,可是面对要求 你总是很无奈,要是可以.mat格式那个很好啊 可是大部分要求都是txt之类的.(不明白为什么呢 其实数据库之类Matlab也是支持的...唉,需求总是最后的注脚...)首先要了解怎么情况会有cell数组产生:具体查看textscan 的说明.大文件的读取首先推荐这个函数,处理灵活可以省去很多功夫,具体的格式设置很关键!能够有效分离cell数据的结果方便处理~否则3000万个数据循环绝对是out of memory...尽量使用高级的IO读写...另外,7.0很多读取都是数值返回cell的char类型数组 7.6以上都使用double了,包括xlsread...
9 L0 v' H7 c0 g如果允许,xlswrite是最好的选择~大量数据测试的结果还是非常好的5 \/ [" }! R7 a& C6 O. `; G' ~ }0 p
在Matlab帮助里面的循环例子:
1 h T! G% i! p) O: P7 M( g0 a( wmycell = { 'a' 1 2 3 ; 'b' 4 5 6 };
7 U' y0 X7 D7 Y$ K) p# y5 g3 F# n[nrows,ncols]= size(mycell);- k/ r/ {. K( a1 @- W8 z( ~
filename = 'celldata.dat';" C+ T: U4 ^$ z7 g
fid = fopen(filename, 'w');0 S3 D5 [- C# q0 v. v
for row=1:nrows
6 P `3 o) K: ` t6 D8 j* u( ^3 Z% y fprintf(fid, '%s %d %d %d\n', mycell{row,:});5 V; J* G$ [$ }1 l8 R) {- }
end
) D# V( Y' B8 Z: \- h1 Q- W* \' Ufclose(fid);
2 F% D y3 |; e5 M) K" k
8 b, @# n( M0 v3 T& X8 ~2 D复制代码) m4 R6 [) Z, `" h3 d4 C6 J: s) |1 U
仅有数值时候 可以考虑先cell2mat 然后csvwrite.
3 q7 Z! h* o1 x8 j- @# d* y/ m) H& V1 n
% H! j8 z. J L5 A
总结5 r: ~3 \9 O, R) ~! K
基本是就是总结了一下用法,特别是转换和保存方面的,相对于struct数组,由于Matlab中支持甚多,因此也就常用了.功能偏弱,但是基本按照规则,还是可以尽量减少出错的.
% K3 ~: A# t( N$ Q' q希望大家也交换一下使用的心得~ |
|