|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
! u; G5 i! n9 r1 {2 `2 ?由于工作需要,经常要处理大量的实验数据.基本都是由仪器导出来,随着社会发展的进步,人们获取数据的量在不断增长,很多人都是,现在已经是海量数据时代了...9 n" K2 r' m; k% u- S
从cell使用说起
/ b! H' t/ ~0 ]$ w8 K' U在读取文件的时候,cell数组(各种翻译都有,元胞数组,单元数组...直接无视)是MATLAB的宠儿,基本都会出现,长期使用发现频率比struct高了不少~无论是Import Data还是使用textscan之类来获取数据.从长期使用高级语言的角度来说,特别是习惯了面向对象之后i,更习惯使用struct数组,概念也很相似,奈何现实是...我们先看一下Matlab在help给出的定义:
. h* Q1 A* L; _0 R: c4 C1 M% WA cell array is a collection of containers called cells in which you can store different types of data.
T5 P; L! S$ _6 j4 C ~1 z. v2 W/ I9 t/ b+ i% y) H$ \
精华之处就是在可以存储不同类型的数据.可以是Matlab的类型或者自定义的类型.( ?5 l) i3 P- a; i" y$ R# M1 F
cell数组的一些操作* S9 P- \+ d" j/ \. h
创建:直接使用{}以及cell(...)形式,另外 下标法赋值也可以.注意后两种可以预配内存,内存是空间连续的~1 _1 V( S! `/ L. r5 Y0 D
读取内容:{下标}和(下标) 区别在于类型()是cell数组 ,{}是实际类型.结果显示是一致的# C+ O' s6 i w7 e: P5 w
>> a={'啊',123,[3 5 6],[1 2;7 8],sym(1)}
" Z, p' n4 C+ W% ba =
1 Y. U7 q6 X3 \' C3 x$ D '啊' [123] [1x3 double] [2x2 double] [1x1 sym]4 Y5 T: d. T s) A( j4 _
>> class(a{1})
! z9 ~, |5 X' v g6 w. \ans =- }7 o$ C* i; [" X @) e
char' `& a( Y! M5 J7 G. t
>> class(a(1))
- N5 K% z, N6 C: y7 v& R0 F( kans =$ q8 e; s" I% ~
cell
$ V* V( q8 ]1 E3 p/ U# ]>> # ]1 G3 Z3 {1 Z& d
C{5,3}{4,7}(:,4): k- n6 j4 @/ `$ i
解读: cell数组的一个元素为cell类型,包含一个普通矩阵类型- K. t& }1 R9 p- N+ _1 a$ w
x = C{5,3}; % x is a cell array
0 U" {) ?& a' Gy = x{4,7}; % y is also a cell array) v/ Y) V' {6 ]5 V7 G3 c/ C
z = y(:,4) % z is a standard array ^, Y6 Q6 U1 s4 B# t# J
复制代码) ]; ]7 _: j! s
调整内容:添加和删除与普通矩阵方法一致
9 s( B9 _+ W' l0 k' P9 c相关函数:2 n. w* G. B0 c
celldisp:显示所有的内容" D: I1 T' m2 J- @* U1 E
cell:创建空的元胞数组
# }& i/ R. X+ w' O5 y cellplot:利用图形方式显示内容5 d, I1 \: ^" i" x
cell2mat:将数组转变成为普通的矩阵 h7 p. D/ v. H4 \
mat2cell:将数值矩阵转变成为cell数组& L: n9 U L# t0 W8 M3 @& G* u
num2cell:将数值数组转变成为cell数组. R5 \ C! `7 K6 a. ^; U
cell2struct:将数组转变成为结构" W) w; j! M' J
struct2cell:将结构转变为cell数组) S, K, P. [* s' d. m" h
iscell:判断输入是否为cell数组
8 H( P+ s% p3 l7 b7 B X5 v* Hcellfun:为cell数组的每个cell执行指定的函数 fun可以是特殊函数或者句柄7 b4 x% Q* H* G# \; b6 e
days{1} = 'Sunday'; days{2} = 'Monday';5 ~# R- [" s4 B; e( p# Z
days{3} = 'TuESDay'; days{4} = 'Wednesday';
1 Q) Z, ~# W& S: y! S! wdays{5} = 'Thursday'; days{6} = 'Friday';
9 a0 r' u+ ]* Y) w9 ~; |; u4 T5 udays{7} = 'Saturday';
. x2 ?3 ?" E% D' d6 C& v
2 d8 Z- N1 U9 f- g9 GshortNames = cellfun(@(x)x(1:3), days, 'UniformOutput', false)
J4 i5 J+ E4 \# w7 c( T* t. F o; vshortNames =
6 d9 i& g: L( I9 J' W 'Sun' 'Mon' 'Tue' 'Wed' 'Thu' 'Fri' 'Sat'
( J5 z5 C# M# _复制代码
6 c U2 F; ^5 c, D deal:将输入参数赋值给输出 [Y1, Y2, Y3, ...] = deal(X{:}) ->可以简化[a,b,c,d] = C{:}+ P. L* v3 a |% ^' R
cell数组的类型转换看到上面的那些类型转换函数,也许你会笑了,感觉也没有什么特别的,但是使用过这个cell数组的朋友,估计大部分都会有转换失败的经历-_-很坑爹的...
) z" q6 c, p5 j( f _0 F3 y4 j/ F$ K/ ~6 X6 |2 }% m
Cell Array and Struct Array
^0 d$ `2 D; Q0 B) h: J; Hs = 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不对' S& S' N$ E5 C
c = struct2cell(s) struct数组转换为cell数组 这个基本没有什么错误的+ r3 J0 d" J0 R& R
V R0 N4 O' M3 jMatrix and Cell Array0 \4 r2 k$ w: z, U! e
c = mat2cell(x, m, n) 转换为 m行n列cell数组 m = cell2mat(c) 必须是同一类型,而且限制不可包含cell数组或object类型,但是struct结构是可以的(同样这个struct不含 cell和object类型,否则依旧出错)
: O4 p) N; z& Q# D
3 z3 x! S( o3 Y. XDouble and Cell Array' X H) V! W% L6 ^& F5 x8 J( k
C = num2cell(A, [dim1, dim2, ...]) 返回C的维数是numel(A)/prod(X,Y,...) dimN 是一个整数,范围是1到ndims(A)! Q3 l* k5 T6 C5 |& y, H+ k- U
只有数值矩阵才可以直接转换为cell,没有供cell转为double的方法.这是非常让人恼火的!不过理解之后就知道,cell本来就是混合类型的,直接转向数值类型单一矩阵,这样是不合理的.通常如果是的确是数值类型的可以走以下路线:cell->cell2mat 这时候注意cell2mat的条件非cell和object.否则,循环或者cellfun处理.如果可以使用 cell2mat 或者cat(dim,c{:}).很多时候都很方便
" M% g+ `8 Z5 y, [! G( x2 k/ HCell Arrays of Strings : J& G; D- h+ U- d
单独列出了是因为很多时候都要接触这个,基本txt之类读取来的数值数据都是char的cell数组~. k1 V- S8 T7 X% s V
可以使用cell参数与字符有关的部分函数(基本都支持)# Z4 C5 Q/ `% N F. f) V+ s
cellstr Convert a character array to a cell array of strings.会去除末尾空白( }0 _. a/ V( D: u! ?
char Convert a cell array of strings to a character array. 会恢复转换时候失去的空白
0 r/ ^8 H, m5 K& J: x. ^deblank Remove trailing blanks from a string.
: l2 T+ D; i. e* piscellstr Return true for acell array of strings.
+ b2 X: D2 t/ Jsort 排序.
5 @" a6 C7 a- ^+ c) U0 j2 M; cstrcat连接字符.3 a( U" S) F4 L q; N) K
strcmp对比字符., G) r" c- _) Z. I
strmatch 查找字符.. O4 O3 V* [- I8 P8 \
strrep 替换字符
5 C2 }7 \# {2 W# {; Oregexp系列及accumarray支持行列向量.) `/ _$ a4 t' f) g( F: G
6 \7 s/ U" g, B! S- i& C; D# e读写9 P+ X+ @. W. K6 q1 g( d
数据读取进来了,处理后当然是需要保存的,可是面对要求 你总是很无奈,要是可以.mat格式那个很好啊 可是大部分要求都是txt之类的.(不明白为什么呢 其实数据库之类Matlab也是支持的...唉,需求总是最后的注脚...)首先要了解怎么情况会有cell数组产生:具体查看textscan 的说明.大文件的读取首先推荐这个函数,处理灵活可以省去很多功夫,具体的格式设置很关键!能够有效分离cell数据的结果方便处理~否则3000万个数据循环绝对是out of memory...尽量使用高级的IO读写...另外,7.0很多读取都是数值返回cell的char类型数组 7.6以上都使用double了,包括xlsread...8 G, i& d. L/ D2 X0 b
如果允许,xlswrite是最好的选择~大量数据测试的结果还是非常好的9 B6 A3 _5 N+ |1 a' u
在Matlab帮助里面的循环例子:
5 q7 |2 A& U9 Q' y) d0 Jmycell = { 'a' 1 2 3 ; 'b' 4 5 6 };* c2 f3 b U# E6 R5 v0 D
[nrows,ncols]= size(mycell);
- ?/ ?3 l$ Y7 y( _* cfilename = 'celldata.dat';0 I9 K* ~6 |4 Y/ Y
fid = fopen(filename, 'w');7 J J% N7 H) P3 F: r- p6 ]8 {
for row=1:nrows
8 _ |+ v+ v7 h; q fprintf(fid, '%s %d %d %d\n', mycell{row,:});, R6 R) I3 e: Q8 Q$ h
end1 |9 b4 v$ h; V5 N- R( E' ]& J5 a
fclose(fid);
$ a' Q- [/ \3 t$ h: W, ?5 [8 M
6 v* I. t! l5 N9 i" Z% Q复制代码
2 V# s( E2 ? l! T( a仅有数值时候 可以考虑先cell2mat 然后csvwrite.
: b; X( [8 Z5 {2 p: y. @1 _) A# E: W) e8 u' R
" g! W& Z5 [$ k总结
0 S" x2 S; [7 }8 q6 I" _基本是就是总结了一下用法,特别是转换和保存方面的,相对于struct数组,由于Matlab中支持甚多,因此也就常用了.功能偏弱,但是基本按照规则,还是可以尽量减少出错的.
# A4 v1 p; P9 ~5 Y2 {希望大家也交换一下使用的心得~ |
|