1. 程式人生 > >matlab中cell陣列的全面介紹

matlab中cell陣列的全面介紹

本文轉載自:http://blog.sina.com.cn/s/blog_8259d70901017wit.html

從cell使用說起
在讀取檔案的時候,cell陣列(各種翻譯都有,元胞陣列,單元陣列...直接無視)是Matlab的寵兒,基本都會出現,長期使用發現頻率比struct高了不少~無論是Import Data還是使用textscan之類來獲取資料.從長期使用高階語言的角度來說,特別是習慣了面向物件之後,更習慣使用struct陣列,概念也很相似,奈何現實是...我們先看一下Matlab在help給出的定義:
A cell array is a collection of containers called cells in which you can store different types of data.

精華之處就是在可以儲存不同型別的資料.可以是Matlab的型別或者自定義的型別.cell陣列的一些操作
  • 建立:直接使用{}以及cell(...)形式,另外 下標法賦值也可以.注意後兩種可以預配記憶體,記憶體是空間連續的~
  • 讀取內容:{下標}和(下標) 區別在於型別()是cell陣列 ,{}是實際型別.結果顯示是一致的
    1. >> a={'啊',123,[3 5 6],[1 2;7 8],sym(1)}
    2. a =
    3.     '啊'    [123]    [1x3 double]    [2x2 double]    [1x1 sym]
    4. >> class(a{1})
    5. ans =
    6. char
    7. >> class(a(1))
    8. ans =
    9. cell
    10. >>a(1)
    11. ans =
    12. 'a'
    13. >>a{1}
    14. ans =
    15. a
  • 調整內容:因為a()表示一個cell,而a{}表示該cell中的內容,因此改變cell陣列中的內容時常用a{},如a{1}='cell',結果為
     a = 


         'cell'    [123]    [1x3 double]    [2x2 double]    [1x1 sym]

      而如果a(1)='cell',則會報錯Conversion to cell from char is not possible.因為等號左邊為一個cell型別而右邊為char型別。若想用a()賦值,則需要將等號右邊也改為cell型。比如令b={'char'};a(1)=b(1),結果為

a = 


    'char'    [123]    [1x3 double]    [2x2 double]    [1x1 sym]

  • 相關函式:
  •   celldisp:顯示所有的內容
  •      cell:建立空的元胞陣列
  •   cellplot:利用圖形方式顯示內容
  •   cell2mat:將陣列轉變成為普通的矩陣
  •   mat2cell:將數值矩陣轉變成為cell陣列
  •   num2cell:將數值陣列轉變成為cell陣列
  •   cell2struct:將陣列轉變成為結構
  •   struct2cell:將結構轉變為cell陣列
  •   iscell:判斷輸入是否為cell陣列
  • cellfun:為cell陣列的每個cell執行指定的函式 fun可以是特殊函式或者控制代碼
    1. days{1} = 'Sunday';    days{2} = 'Monday';
    2. days{3} = 'Tuesday';   days{4} = 'Wednesday';
    3. days{5} = 'Thursday';  days{6} = 'Friday';
    4. days{7} = 'Saturday';
    5. shortNames = cellfun(@(x)x(1:3), days, 'UniformOutput', false)
    6. shortNames =
    7.     'Sun'    'Mon'    'Tue'    'Wed'    'Thu'    'Fri'    'Sat'
    複製程式碼
  •   deal:將輸入引數賦值給輸出 [Y1, Y2, Y3, ...] = deal(X{:}) ->可以簡化[a,b,c,d] = C{:}
cell陣列的型別轉換看到上面的那些型別轉換函式,也許你會笑了,感覺也沒有什麼特別的,但是使用過這個cell陣列的朋友,估計大部分都會有轉換失敗的經歷-_-很坑爹的...

Cell Array and Struct Array
  • 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不對
  •    c = struct2cell(s)  struct陣列轉換為cell陣列 這個基本沒有什麼錯誤的

Matrix and Cell Array
c = mat2cell(x, m, n) 轉換為 m行n列cell陣列 m = cell2mat(c) 必須是同一型別,而且限制不可包含cell陣列或object型別,但是struct結構是可以的(同樣這個struct不含 cell和object型別,否則依舊出錯)

Double and Cell Array
C = num2cell(A, [dim1, dim2, ...]) 返回C的維數是numel(A)/prod(X,Y,...)   dimN 是一個整數,範圍是1到ndims(A)
只有數值矩陣才可以直接轉換為cell,沒有供cell轉為double的方法.這是非常讓人惱火的!不過理解之後就知道,cell本來就是混合型別的,直接轉向數值型別單一矩陣,這樣是不合理的.通常如果是的確是數值型別的可以走以下路線:cell->cell2mat 這時候注意cell2mat的條件非cell和object.否則,迴圈或者cellfun處理.如果可以使用 cell2mat 或者cat(dim,c{:}).很多時候都很方便
Cell Arrays of Strings
單獨列出了是因為很多時候都要接觸這個,基本txt之類讀取來的數值資料都是char的cell陣列~
可以使用cell引數與字元有關的部分函式(基本都支援)
  • cellstr      Convert a character array to a cell array of strings.會去除末尾空白
  • char        Convert a cell array of strings to a character array. 會恢復轉換時候失去的空白
  • deblank   Remove trailing blanks from a string.
  • iscellstr    Return true for acell array of strings.
  • sort        排序.
  • strcat連線字元.
  • strcmp對比字元.
  • strmatch 查詢字元.
  • strrep 替換字元
  • regexp系列及accumarray支援行列向量.

讀寫
資料讀取進來了,處理後當然是需要儲存的,可是面對要求 你總是很無奈,要是可以.mat格式那個很好啊 可是大部分要求都是txt之類的.(不明白為什麼呢 其實資料庫之類Matlab也是支援的...唉,需求總是最後的註腳...)首

先要了解怎麼情況會有cell陣列產生:具體檢視textscan 的說明.大檔案的讀取首先推薦這個函式,處理靈活可以省去很多功夫,具體的格式設定很關鍵!能夠有效分離cell資料的結果方便處理~否則3000萬個資料迴圈絕對是out of memory...儘量使用高階的IO讀寫...另外,7.0很多讀取都是數值返回cell的char型別陣列 7.6以上都使用double了,包括xlsread...
如果允許,xlswrite是最好的選擇~大量資料測試的結果還是非常好的
在Matlab幫助裡面的迴圈例子:

  1. mycell = { 'a' 1 2 3 ; 'b' 4 5 6 };
  2. [nrows,ncols]= size(mycell);
  3. filename = 'celldata.dat';
  4. fid = fopen(filename, 'w');
  5. for row=1:nrows
  6.     fprintf(fid, '%s %d %d %d\n', mycell{row,:});
  7. end
  8. fclose(fid);
複製程式碼僅有數值時候 可以考慮先cell2mat 然後csvwrite.
cellfun的例子可以參考Matlab公司的http://www.mathworks.cn/support/solutions/en/data/1-1190ZB/index.html?solution=1-1190ZB

總結
基本是就是總結了一下用法,特別是轉換和儲存方面的,相對於struct陣列,由於Matlab中支援甚多,因此也就常用了.功能偏弱,但是基本按照規則,還是可以儘量減少出錯的.
希望大家也交換一下使用的心得~