|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
* ]( b( q$ N( T1 O3 f
由于工作需要,经常要处理大量的实验数据.基本都是由仪器导出来,随着社会发展的进步,人们获取数据的量在不断增长,很多人都是,现在已经是海量数据时代了...
+ s) F% I U. i+ k0 c* }从cell使用说起 3 y3 T, I' z9 X; E/ k4 N
在读取文件的时候,cell数组(各种翻译都有,元胞数组,单元数组...直接无视)是MATLAB的宠儿,基本都会出现,长期使用发现频率比struct高了不少~无论是Import Data还是使用textscan之类来获取数据.从长期使用高级语言的角度来说,特别是习惯了面向对象之后i,更习惯使用struct数组,概念也很相似,奈何现实是...我们先看一下Matlab在help给出的定义:6 D7 [ D. t+ {8 R
A cell array is a collection of containers called cells in which you can store different types of data.
0 @$ t: x' U9 k; m
/ {% j( o3 b0 d7 `: D精华之处就是在可以存储不同类型的数据.可以是Matlab的类型或者自定义的类型.& N8 m$ k W h }% l& _% H/ P
cell数组的一些操作
7 D) l+ z0 A/ R: G {, ~$ ~' ~& }: Z创建:直接使用{}以及cell(...)形式,另外 下标法赋值也可以.注意后两种可以预配内存,内存是空间连续的~; I% X: e* ~) P
读取内容:{下标}和(下标) 区别在于类型()是cell数组 ,{}是实际类型.结果显示是一致的( ]* s- x, a3 U1 H5 ~ m
>> a={'啊',123,[3 5 6],[1 2;7 8],sym(1)}' F5 {. e# y, x1 q5 {# a
a =
9 _' p# ]$ E% a R '啊' [123] [1x3 double] [2x2 double] [1x1 sym]
7 ?) H6 O- X+ d. _, m/ o7 ]; X8 {>> class(a{1})3 M1 p6 T0 E3 q! Y
ans =8 U2 R$ y+ g/ k! S9 R4 a
char
( n; ?5 Q# i: G5 m% g" z- Y>> class(a(1))
1 x( S/ g8 ^! N4 A, c1 lans =/ A+ z( R8 t8 Y. F4 Z$ J
cell
! q8 h7 X4 f7 h8 n5 m4 Q! y4 D; t>>
* X- L0 B$ g/ y: h7 RC{5,3}{4,7}(:,4)
9 b' g! t. v0 W" a$ H0 }& t& d# ~解读: cell数组的一个元素为cell类型,包含一个普通矩阵类型
# W3 M* Y" L3 z, B$ Lx = C{5,3}; % x is a cell array
7 H- s$ ]3 ?# D# k5 s6 Z9 d! t) F1 @y = x{4,7}; % y is also a cell array: O% I1 s( {3 d
z = y(:,4) % z is a standard array0 z2 U1 o! o [# `' L
复制代码; ?* X/ ` a5 y1 E
调整内容:添加和删除与普通矩阵方法一致
, C" ]7 H1 R& {相关函数:9 @4 M& ?5 y/ A+ d2 e' ^# G- G o1 Z
celldisp:显示所有的内容# Z+ w% @. s p+ o1 s4 g/ e+ Y: C
cell:创建空的元胞数组
1 N, k6 ?. a9 ~* h0 \ cellplot:利用图形方式显示内容) r9 k: X4 D( \/ \4 o. v
cell2mat:将数组转变成为普通的矩阵0 e. m+ {/ ]: C! F' T$ o8 I
mat2cell:将数值矩阵转变成为cell数组7 K& h% W7 f; w' V
num2cell:将数值数组转变成为cell数组/ A; x3 H, `) K$ F8 m w; J
cell2struct:将数组转变成为结构
/ |6 r5 O4 c% d W. k0 @) S0 H struct2cell:将结构转变为cell数组
$ a0 N, y+ \( ` | iscell:判断输入是否为cell数组
. Y8 c6 {; h* C( h5 [cellfun:为cell数组的每个cell执行指定的函数 fun可以是特殊函数或者句柄% ^" `/ B- a h. [# _
days{1} = 'Sunday'; days{2} = 'Monday';$ |- r6 g2 a# ]8 l
days{3} = 'TuESDay'; days{4} = 'Wednesday';
4 u' E1 F, [3 A4 G; D2 g+ tdays{5} = 'Thursday'; days{6} = 'Friday';
2 v7 ^3 W" Z; d& mdays{7} = 'Saturday';2 l4 V$ G, _5 q# J- T
$ ^" s1 d; @$ l ?- ~. \
shortNames = cellfun(@(x)x(1:3), days, 'UniformOutput', false)
; `7 Z- l# ~# Y. R$ qshortNames = . y1 A8 c' t9 Z6 I
'Sun' 'Mon' 'Tue' 'Wed' 'Thu' 'Fri' 'Sat'
! v2 `8 o+ |/ r" O9 j X复制代码) b* X3 A; U5 c: m! C
deal:将输入参数赋值给输出 [Y1, Y2, Y3, ...] = deal(X{:}) ->可以简化[a,b,c,d] = C{:}0 s$ C0 z, w+ _+ {. a5 Z# t
cell数组的类型转换看到上面的那些类型转换函数,也许你会笑了,感觉也没有什么特别的,但是使用过这个cell数组的朋友,估计大部分都会有转换失败的经历-_-很坑爹的...' z- ]6 f8 K1 N `( A: P
* U2 E* w$ u. \5 U) a3 bCell Array and Struct Array
" O. n; k4 u. y5 Ts = 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不对: a$ D- \; ~( ?) G( Q/ n+ w
c = struct2cell(s) struct数组转换为cell数组 这个基本没有什么错误的
) x! T9 t) H/ W! N; s! l; x
8 c6 ^0 H6 J2 j4 S) bMatrix and Cell Array$ m8 w8 f% m! u3 `: u
c = mat2cell(x, m, n) 转换为 m行n列cell数组 m = cell2mat(c) 必须是同一类型,而且限制不可包含cell数组或object类型,但是struct结构是可以的(同样这个struct不含 cell和object类型,否则依旧出错), X) O! i& S, P6 A
+ O6 i6 W9 B2 m
Double and Cell Array$ C i8 C% O* p- J
C = num2cell(A, [dim1, dim2, ...]) 返回C的维数是numel(A)/prod(X,Y,...) dimN 是一个整数,范围是1到ndims(A)
; }% W1 y. s4 G# D, O J! J! X- R只有数值矩阵才可以直接转换为cell,没有供cell转为double的方法.这是非常让人恼火的!不过理解之后就知道,cell本来就是混合类型的,直接转向数值类型单一矩阵,这样是不合理的.通常如果是的确是数值类型的可以走以下路线:cell->cell2mat 这时候注意cell2mat的条件非cell和object.否则,循环或者cellfun处理.如果可以使用 cell2mat 或者cat(dim,c{:}).很多时候都很方便
! Z V: v0 r1 F! `& E. CCell Arrays of Strings " H. |% t, i) E' _; w
单独列出了是因为很多时候都要接触这个,基本txt之类读取来的数值数据都是char的cell数组~( i+ |9 H/ h# \
可以使用cell参数与字符有关的部分函数(基本都支持); G& \/ `5 t* h) }3 n, N
cellstr Convert a character array to a cell array of strings.会去除末尾空白* e* C; d; R v% X# F# X- M" o
char Convert a cell array of strings to a character array. 会恢复转换时候失去的空白
5 q! y/ f" F& { Xdeblank Remove trailing blanks from a string.- J- k+ U( _. u9 l% ^" a, |( K
iscellstr Return true for acell array of strings.0 Z3 h, N! n, t- d
sort 排序.
4 V" U* j9 ~8 d( W* p N' Fstrcat连接字符.
' A/ x! R7 E3 f! g9 S/ X2 P- c w! K% cstrcmp对比字符.0 {/ `3 h- N: a2 v6 n
strmatch 查找字符.! d* }3 ^, L5 E0 g5 O
strrep 替换字符
3 e/ [* k( |5 U. \; D# \# jregexp系列及accumarray支持行列向量.
4 R. T2 }! z0 e6 s
5 I9 ~3 `( u- H+ n0 S$ n" ~9 @读写3 L# }0 |& ^8 @6 Q$ o3 Z
数据读取进来了,处理后当然是需要保存的,可是面对要求 你总是很无奈,要是可以.mat格式那个很好啊 可是大部分要求都是txt之类的.(不明白为什么呢 其实数据库之类Matlab也是支持的...唉,需求总是最后的注脚...)首先要了解怎么情况会有cell数组产生:具体查看textscan 的说明.大文件的读取首先推荐这个函数,处理灵活可以省去很多功夫,具体的格式设置很关键!能够有效分离cell数据的结果方便处理~否则3000万个数据循环绝对是out of memory...尽量使用高级的IO读写...另外,7.0很多读取都是数值返回cell的char类型数组 7.6以上都使用double了,包括xlsread...4 Y. J! H; K! f4 |) H5 i1 m$ P4 R
如果允许,xlswrite是最好的选择~大量数据测试的结果还是非常好的
6 G* u9 c. z' U) J在Matlab帮助里面的循环例子:
& ], Q, P8 g' ?0 `" Y3 Amycell = { 'a' 1 2 3 ; 'b' 4 5 6 };
& s8 @+ O" ~4 C4 W[nrows,ncols]= size(mycell);. O- H8 `& H+ y4 K# F q. g, f- l
filename = 'celldata.dat';
; K$ W0 ?/ ]1 r+ x, {fid = fopen(filename, 'w');
% C9 B! s) t# D9 Sfor row=1:nrows
9 Y* C+ e2 d) U! A9 o+ Q. h9 w fprintf(fid, '%s %d %d %d\n', mycell{row,:});
, L9 T9 y/ N y; e% Rend; B3 n" U# m0 S
fclose(fid);
% F$ P4 i) [1 o9 r9 {3 R
- T9 z" e2 Y7 [( v% s) B. t复制代码
- N* Z* G: {$ W9 n& T' {仅有数值时候 可以考虑先cell2mat 然后csvwrite.# c( L K2 _1 t0 g
. K) ^) L+ u+ |3 d, F7 J! H& K9 c1 \ Q3 H3 f' C. R( h% o6 Y" A
总结7 W0 k1 i$ M& h6 m
基本是就是总结了一下用法,特别是转换和保存方面的,相对于struct数组,由于Matlab中支持甚多,因此也就常用了.功能偏弱,但是基本按照规则,还是可以尽量减少出错的.
2 |/ e" i% q$ D( j6 O1 U# |% X希望大家也交换一下使用的心得~ |
|