|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
3 N. Q" `+ ~7 n; `0 d7 O: \
由于工作需要,经常要处理大量的实验数据.基本都是由仪器导出来,随着社会发展的进步,人们获取数据的量在不断增长,很多人都是,现在已经是海量数据时代了...
0 f4 t2 q( b6 u2 i0 l, L2 g从cell使用说起 7 D6 _( \" Y) M, K7 s6 w. M
在读取文件的时候,cell数组(各种翻译都有,元胞数组,单元数组...直接无视)是MATLAB的宠儿,基本都会出现,长期使用发现频率比struct高了不少~无论是Import Data还是使用textscan之类来获取数据.从长期使用高级语言的角度来说,特别是习惯了面向对象之后i,更习惯使用struct数组,概念也很相似,奈何现实是...我们先看一下Matlab在help给出的定义:
8 d S& X- |/ xA cell array is a collection of containers called cells in which you can store different types of data.
# C6 S5 y; {; U3 ~2 M
5 N3 l5 @) ?& L. N0 e* Z* ^精华之处就是在可以存储不同类型的数据.可以是Matlab的类型或者自定义的类型.9 y- s' s7 m+ a: o+ l- I/ s% e: M' U
cell数组的一些操作' U2 u5 Z! }) l, h
创建:直接使用{}以及cell(...)形式,另外 下标法赋值也可以.注意后两种可以预配内存,内存是空间连续的~5 J0 l5 l& e" I. I4 {& z5 K
读取内容:{下标}和(下标) 区别在于类型()是cell数组 ,{}是实际类型.结果显示是一致的* Q9 Q _$ k( x: `# u6 I' X
>> a={'啊',123,[3 5 6],[1 2;7 8],sym(1)}7 R# W. } J2 C5 S
a =
4 Q7 T6 v. M: @* F! ` '啊' [123] [1x3 double] [2x2 double] [1x1 sym]
# j' n; U. R+ V, S>> class(a{1})" S7 D" ]- M( @1 \9 F, e
ans =
2 ]( r/ D) |( ?1 ~! [9 Lchar
9 o" E, m# I( U, P& x>> class(a(1))
( t1 C" K8 Y+ m; Kans =
7 {7 t' N- ]9 {1 U/ e; ecell
% q" Z8 ?; `' |>>
0 g; A1 m- }6 s3 ?7 T4 vC{5,3}{4,7}(:,4)
; u* A$ Z- |8 q$ S' R6 m- s解读: cell数组的一个元素为cell类型,包含一个普通矩阵类型/ g. A8 x; y" f% K H
x = C{5,3}; % x is a cell array/ f. `0 u9 T; n& p' s
y = x{4,7}; % y is also a cell array
" {4 {# O: [4 e& N! }z = y(:,4) % z is a standard array
% }5 }1 Z; C7 c# L7 m3 p8 O$ s1 W5 @复制代码
5 Z& ^( e0 ^0 Z7 L" }% ?% ^1 H调整内容:添加和删除与普通矩阵方法一致
+ ? j7 u7 K, D相关函数:' X8 B: E$ g( T5 C
celldisp:显示所有的内容
+ R6 q' @' O8 @2 @; Fcell:创建空的元胞数组
3 v- v* i$ x& E: E" T: c cellplot:利用图形方式显示内容
% i) n" c( p; r) x7 `& ?, W$ E cell2mat:将数组转变成为普通的矩阵
" ~8 l7 j X; \% G mat2cell:将数值矩阵转变成为cell数组
( C9 ^5 G( [# z3 c0 O num2cell:将数值数组转变成为cell数组1 L/ H( q7 B) M/ {$ O1 Y2 w
cell2struct:将数组转变成为结构4 w7 K- M# @6 z; P _6 r
struct2cell:将结构转变为cell数组& g) [! S0 v* p: D0 i2 Y
iscell:判断输入是否为cell数组
`! y6 Q) B, ?# `# z6 c7 Ucellfun:为cell数组的每个cell执行指定的函数 fun可以是特殊函数或者句柄
8 G2 o3 y" p- n' Vdays{1} = 'Sunday'; days{2} = 'Monday';" b6 z( ^9 \3 D! i% {3 l
days{3} = 'TuESDay'; days{4} = 'Wednesday';3 F Y4 e" i7 a% K; f4 W9 y3 ~
days{5} = 'Thursday'; days{6} = 'Friday';
7 ^9 s" H" S* f3 ]days{7} = 'Saturday';- f5 @% h3 B) K# V; e) v9 M
6 k" g5 h' T) z3 {
shortNames = cellfun(@(x)x(1:3), days, 'UniformOutput', false)
$ |; j: j" a5 }# H+ ]1 R7 jshortNames =
! W0 r1 y# h0 f! \7 X1 E# [; z 'Sun' 'Mon' 'Tue' 'Wed' 'Thu' 'Fri' 'Sat'! `0 i V7 z" F6 q" i( f" ~
复制代码1 M3 u5 ~8 r1 [8 K( f7 e- A4 W5 k
deal:将输入参数赋值给输出 [Y1, Y2, Y3, ...] = deal(X{:}) ->可以简化[a,b,c,d] = C{:}/ R$ X1 e& ~7 y" {9 W
cell数组的类型转换看到上面的那些类型转换函数,也许你会笑了,感觉也没有什么特别的,但是使用过这个cell数组的朋友,估计大部分都会有转换失败的经历-_-很坑爹的...
' k- X( j( k9 d: _* o9 ]7 b, _
M3 O/ g' g2 [9 L4 [- gCell Array and Struct Array0 q" |( b9 b) J; ]# ^2 H' T7 E
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不对% I* |6 B* u" p% M
c = struct2cell(s) struct数组转换为cell数组 这个基本没有什么错误的+ h% ?2 Q5 J! g' b- T/ \7 q
' b5 m; Y% g$ m" @9 fMatrix and Cell Array
& e1 p/ l8 ?0 D6 yc = mat2cell(x, m, n) 转换为 m行n列cell数组 m = cell2mat(c) 必须是同一类型,而且限制不可包含cell数组或object类型,但是struct结构是可以的(同样这个struct不含 cell和object类型,否则依旧出错)# Y" U" W1 Q0 z2 c/ \( |( h
& c! t$ X1 P7 x O' ]) a! ^
Double and Cell Array9 i1 ~2 r1 D3 M; S9 c( {
C = num2cell(A, [dim1, dim2, ...]) 返回C的维数是numel(A)/prod(X,Y,...) dimN 是一个整数,范围是1到ndims(A)
- e* @5 h+ f) W! G) I8 E只有数值矩阵才可以直接转换为cell,没有供cell转为double的方法.这是非常让人恼火的!不过理解之后就知道,cell本来就是混合类型的,直接转向数值类型单一矩阵,这样是不合理的.通常如果是的确是数值类型的可以走以下路线:cell->cell2mat 这时候注意cell2mat的条件非cell和object.否则,循环或者cellfun处理.如果可以使用 cell2mat 或者cat(dim,c{:}).很多时候都很方便
/ s5 _) ?" N, ?Cell Arrays of Strings * ^ Z- V0 E8 j m) h
单独列出了是因为很多时候都要接触这个,基本txt之类读取来的数值数据都是char的cell数组~! T# h0 A' G' w) v
可以使用cell参数与字符有关的部分函数(基本都支持)
! ^5 }1 N. d1 {6 a( e! C+ Xcellstr Convert a character array to a cell array of strings.会去除末尾空白( z' X a6 c6 o- b) \
char Convert a cell array of strings to a character array. 会恢复转换时候失去的空白
7 U! R) o% _( [! l) Udeblank Remove trailing blanks from a string.
# w; i- u( a) tiscellstr Return true for acell array of strings.7 X7 O. \4 [& u2 l2 V$ l* q
sort 排序.1 f: F' Q6 E& j7 Y& a
strcat连接字符.6 }% s! G, E4 Z S. E- R. K" C
strcmp对比字符.2 Z3 [( Z3 g/ |0 p+ W* {5 @
strmatch 查找字符.
9 s( B7 z+ C, O0 W6 M" lstrrep 替换字符
" ?& E" a' m. c1 sregexp系列及accumarray支持行列向量.
) [3 \& q4 t' k7 v. u" T+ @/ }) H) S Y7 G/ c) G- e
读写
5 X' D6 M4 A3 S1 i6 e' M0 q5 j$ ?0 C! v. p1 o数据读取进来了,处理后当然是需要保存的,可是面对要求 你总是很无奈,要是可以.mat格式那个很好啊 可是大部分要求都是txt之类的.(不明白为什么呢 其实数据库之类Matlab也是支持的...唉,需求总是最后的注脚...)首先要了解怎么情况会有cell数组产生:具体查看textscan 的说明.大文件的读取首先推荐这个函数,处理灵活可以省去很多功夫,具体的格式设置很关键!能够有效分离cell数据的结果方便处理~否则3000万个数据循环绝对是out of memory...尽量使用高级的IO读写...另外,7.0很多读取都是数值返回cell的char类型数组 7.6以上都使用double了,包括xlsread...- \2 _; i, V7 C5 q; z
如果允许,xlswrite是最好的选择~大量数据测试的结果还是非常好的
( f4 I: a7 Y: Z u5 N在Matlab帮助里面的循环例子:( @; |0 b, S# X. P( g5 a! ^
mycell = { 'a' 1 2 3 ; 'b' 4 5 6 };
n3 B6 h% ]: U: Z) Z5 z3 g[nrows,ncols]= size(mycell);# U+ j" I2 d5 |8 o2 |* i; `! R
filename = 'celldata.dat';
2 I5 B( @9 `9 Q/ xfid = fopen(filename, 'w');
U* i- A, m, ^1 ]' b! Ifor row=1:nrows
) ?; ^% D1 @% ~3 h+ M5 D fprintf(fid, '%s %d %d %d\n', mycell{row,:});
0 c2 |$ e: L+ Wend
' E9 j0 Y2 ?& J/ { Ifclose(fid);
& N; {7 P6 w4 w; n: \9 l, P; }% ^% _3 k" L0 a8 Y; j9 j
复制代码; t. n+ s+ i! z# o/ N! U6 m. z
仅有数值时候 可以考虑先cell2mat 然后csvwrite.
* K6 c+ U0 M* w: y/ ~0 b! V
, l9 h: ?- T n2 D9 ~: K0 N0 Q: e) y/ p( @9 ^2 D) \
总结
' `5 n# {$ }/ H& `2 |$ n7 Z基本是就是总结了一下用法,特别是转换和保存方面的,相对于struct数组,由于Matlab中支持甚多,因此也就常用了.功能偏弱,但是基本按照规则,还是可以尽量减少出错的.' @3 g( f5 z' P0 l
希望大家也交换一下使用的心得~ |
|