|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
6 d0 q$ I" _; K* k& v由于工作需要,经常要处理大量的实验数据.基本都是由仪器导出来,随着社会发展的进步,人们获取数据的量在不断增长,很多人都是,现在已经是海量数据时代了...2 j+ W3 Z+ U! K7 P: u
从cell使用说起
/ W- O* M. D& v' L! E# ]# M在读取文件的时候,cell数组(各种翻译都有,元胞数组,单元数组...直接无视)是MATLAB的宠儿,基本都会出现,长期使用发现频率比struct高了不少~无论是Import Data还是使用textscan之类来获取数据.从长期使用高级语言的角度来说,特别是习惯了面向对象之后i,更习惯使用struct数组,概念也很相似,奈何现实是...我们先看一下Matlab在help给出的定义:
& b$ s! k8 }$ E) i) hA cell array is a collection of containers called cells in which you can store different types of data.+ @ p, j/ g( f! `0 F: w( Q' _
$ X' v. c+ o N+ T
精华之处就是在可以存储不同类型的数据.可以是Matlab的类型或者自定义的类型.
, o; V7 A& v7 a( M" wcell数组的一些操作! c: m- Z0 f# b0 c: T' F8 _1 u
创建:直接使用{}以及cell(...)形式,另外 下标法赋值也可以.注意后两种可以预配内存,内存是空间连续的~6 _" `. Z. i8 n, l/ V7 X
读取内容:{下标}和(下标) 区别在于类型()是cell数组 ,{}是实际类型.结果显示是一致的8 c& E n$ p: E( |3 E6 J. b+ J
>> a={'啊',123,[3 5 6],[1 2;7 8],sym(1)}+ @7 E' N, C( I0 i
a =
; w! N& o: \) ]7 x& W( p. I2 ^ '啊' [123] [1x3 double] [2x2 double] [1x1 sym]; c& D7 X% }3 s* y# i% i
>> class(a{1})
) q; \. J, {4 Jans =
- n, ^% }. D5 H2 [char
4 q$ x1 g7 ]8 p: M>> class(a(1))
2 U7 v3 k: V. c1 e3 V$ f, sans =
|: m3 v2 z, |* ^cell
) Z3 @$ z2 }" S1 p>>
# _# e4 ?& @" c$ bC{5,3}{4,7}(:,4)
- I! X( I6 m8 L" i解读: cell数组的一个元素为cell类型,包含一个普通矩阵类型1 V" {$ r% f: K0 y
x = C{5,3}; % x is a cell array/ w; B3 J) ]! c8 b3 u' }
y = x{4,7}; % y is also a cell array" L: [7 R* V, I& }0 p# x+ [, v" b! e
z = y(:,4) % z is a standard array: x& G* e e# H9 Q* V8 ^9 V
复制代码
0 Y5 [# M) h4 x& M; D, A调整内容:添加和删除与普通矩阵方法一致
% v! r$ w, o4 N2 V% q( I6 Q( s相关函数:
% [6 @$ @& v6 x+ n) }# p$ q, C' I: V celldisp:显示所有的内容
8 ?9 X% w! ]* }! f( y( P2 H# P9 v7 x3 kcell:创建空的元胞数组1 m, V4 o3 E- d: b) T
cellplot:利用图形方式显示内容
- P1 W. Y. \7 r$ }+ m cell2mat:将数组转变成为普通的矩阵, A9 j" W1 d1 @. o. F2 [! a
mat2cell:将数值矩阵转变成为cell数组4 v8 O1 Y* t# t% k2 R
num2cell:将数值数组转变成为cell数组& l2 I7 U1 D0 Q" r6 b
cell2struct:将数组转变成为结构
' T4 s1 X; y; N9 k9 O. F- |" G% K struct2cell:将结构转变为cell数组/ s+ t. i/ c' G4 F; l0 F" ~
iscell:判断输入是否为cell数组. ^" G- {7 y4 V4 Z2 X$ P' q! c8 n
cellfun:为cell数组的每个cell执行指定的函数 fun可以是特殊函数或者句柄
' G* y9 g! e; x7 ~5 N! Q' zdays{1} = 'Sunday'; days{2} = 'Monday';
% ]' X# j3 Z) _- Q3 Z) }, gdays{3} = 'TuESDay'; days{4} = 'Wednesday';
+ J- ? G1 ^8 r( Q5 Udays{5} = 'Thursday'; days{6} = 'Friday';
4 o7 t/ w, }0 t3 P$ Udays{7} = 'Saturday';
) M8 R3 _( U) L/ t& {8 C* E1 l s7 q( N6 X" i: q6 x1 m) Y( M/ @/ ]
shortNames = cellfun(@(x)x(1:3), days, 'UniformOutput', false)0 R9 [4 M/ b$ m z5 g
shortNames =
( u/ |' U, `6 ^; n 'Sun' 'Mon' 'Tue' 'Wed' 'Thu' 'Fri' 'Sat'
0 D0 j4 h/ x' h4 O+ v3 T5 Z w; x复制代码' M- |+ E6 q" k3 D/ `$ q2 a
deal:将输入参数赋值给输出 [Y1, Y2, Y3, ...] = deal(X{:}) ->可以简化[a,b,c,d] = C{:}* \( P& L0 R' b# C. v
cell数组的类型转换看到上面的那些类型转换函数,也许你会笑了,感觉也没有什么特别的,但是使用过这个cell数组的朋友,估计大部分都会有转换失败的经历-_-很坑爹的...% C7 b2 R2 A6 b# Y9 J+ z6 x+ d6 h. y# [
. v; G2 j* n! T
Cell Array and Struct Array2 `; d8 e/ V$ Q' x
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不对
, ?$ y' q8 Z: p1 m# b% M4 r4 z1 z3 q c = struct2cell(s) struct数组转换为cell数组 这个基本没有什么错误的, x1 m8 X6 [! M. Y' u: F6 j; Z3 }6 Q, l
& X0 w; p' w, J/ {& c) ]Matrix and Cell Array
, ~$ L8 U" D" x" z& @' q6 C! p* Vc = mat2cell(x, m, n) 转换为 m行n列cell数组 m = cell2mat(c) 必须是同一类型,而且限制不可包含cell数组或object类型,但是struct结构是可以的(同样这个struct不含 cell和object类型,否则依旧出错)0 Z- e% ]5 b; B1 ?- u. Q, m
& c; G6 |; Q0 A8 K/ y. kDouble and Cell Array4 T$ J' _- Q* V
C = num2cell(A, [dim1, dim2, ...]) 返回C的维数是numel(A)/prod(X,Y,...) dimN 是一个整数,范围是1到ndims(A)3 ?( j* Z$ m8 U R# E
只有数值矩阵才可以直接转换为cell,没有供cell转为double的方法.这是非常让人恼火的!不过理解之后就知道,cell本来就是混合类型的,直接转向数值类型单一矩阵,这样是不合理的.通常如果是的确是数值类型的可以走以下路线:cell->cell2mat 这时候注意cell2mat的条件非cell和object.否则,循环或者cellfun处理.如果可以使用 cell2mat 或者cat(dim,c{:}).很多时候都很方便+ A4 I& I3 l8 |$ x9 W
Cell Arrays of Strings " e4 {- ^) a/ \! g. {, X; L
单独列出了是因为很多时候都要接触这个,基本txt之类读取来的数值数据都是char的cell数组~
! B& S5 n- d8 v3 \) {- x可以使用cell参数与字符有关的部分函数(基本都支持)
y/ Q0 f3 J( X! @7 q9 Y9 wcellstr Convert a character array to a cell array of strings.会去除末尾空白4 c! K# Q; z% ?" B
char Convert a cell array of strings to a character array. 会恢复转换时候失去的空白, P7 G/ e: e* D# l/ B5 G
deblank Remove trailing blanks from a string.! d+ o& Q1 C$ Y# ~/ F8 W
iscellstr Return true for acell array of strings.
/ g) i$ Q) l' q1 J+ B2 Lsort 排序.
2 z9 U. M7 T7 Jstrcat连接字符.
4 D) N- b# S0 D3 Zstrcmp对比字符.
P- \' ~, h: e* Istrmatch 查找字符.
2 _" t6 L+ c, nstrrep 替换字符( X$ q, y& ^9 f2 w) K# x
regexp系列及accumarray支持行列向量.# G: z" J5 w5 A) o
) h4 r) i+ `: s3 ]4 B5 V1 n读写! Z8 j0 R y, |# W( |
数据读取进来了,处理后当然是需要保存的,可是面对要求 你总是很无奈,要是可以.mat格式那个很好啊 可是大部分要求都是txt之类的.(不明白为什么呢 其实数据库之类Matlab也是支持的...唉,需求总是最后的注脚...)首先要了解怎么情况会有cell数组产生:具体查看textscan 的说明.大文件的读取首先推荐这个函数,处理灵活可以省去很多功夫,具体的格式设置很关键!能够有效分离cell数据的结果方便处理~否则3000万个数据循环绝对是out of memory...尽量使用高级的IO读写...另外,7.0很多读取都是数值返回cell的char类型数组 7.6以上都使用double了,包括xlsread..., [4 j& G" S1 X8 ]# P7 ^
如果允许,xlswrite是最好的选择~大量数据测试的结果还是非常好的
) N- A( w7 i& q在Matlab帮助里面的循环例子:
" o- M: r8 _" D! O9 [# ^, Wmycell = { 'a' 1 2 3 ; 'b' 4 5 6 };
! i5 s& \( G; i2 K! S/ m0 t% P2 c[nrows,ncols]= size(mycell);( D. q( z5 }9 C J, e
filename = 'celldata.dat';
+ U/ Z: z+ ~/ m. u2 _8 K. C1 r% cfid = fopen(filename, 'w');. Z" v2 d' {$ Y9 K
for row=1:nrows# U* ^" s4 a# m, W7 I3 Q: A
fprintf(fid, '%s %d %d %d\n', mycell{row,:});
0 {9 F' {- d4 V3 T# Qend
1 W* ~. {: E1 d8 H7 Z5 X. Afclose(fid);5 @- l& v; M0 B7 U" F
0 ]7 N- i: |7 e. U复制代码; c$ e: U( l' p3 v: a
仅有数值时候 可以考虑先cell2mat 然后csvwrite.
- f" |$ n/ z k0 j5 M/ d9 V6 m6 I$ Z* ]
8 v* x7 b# V8 {8 \8 S! w总结
9 q- S0 Y; L' O: Z' H) o" P( H+ X基本是就是总结了一下用法,特别是转换和保存方面的,相对于struct数组,由于Matlab中支持甚多,因此也就常用了.功能偏弱,但是基本按照规则,还是可以尽量减少出错的.
* ?. d5 O/ [) u( o7 U希望大家也交换一下使用的心得~ |
|