【zz】MATLAB中cell數組的是是非非


原文地址:http://www.matlabsky.com/forum.php?mod=viewthread&tid=21089

從cell使用說起 
在讀取文件的時候,cell數組(各種翻譯都有,元胞數組,單元數組...直接無視)是Matlab的寵兒,基本都會出現,長期使用發現頻率比struct高了不少~無論是Import Data還是使用textscan之類來獲取數據.從長期使用高級語言的角度來說,特別是習慣了面向對象之后i,更習慣使用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數組 ,{}是實際類型.結果顯示是一致的
    >> a={'',123,[3 5 6],[1 2;7 8],sym(1)}
    a = 
        ''    [123]    [1x3 double]    [2x2 double]    [1x1 sym]
    >> class(a{1})
    ans =
    char
    >> class(a(1))
    ans =
    cell
    >> 
    C{5,3}{4,7}(:,4)
    解讀: cell數組的一個元素為cell類型,包含一個普通矩陣類型
    x = C{5,3};      % x is a cell array
    y = x{4,7};      % y is also a cell array
    z = y(:,4)       % z is a standard array

     

  • 調整內容:添加和刪除與普通矩陣方法一致
  • 相關函數:
  •   celldisp:顯示所有的內容
  • cell:創建空的元胞數組
  •   cellplot:利用圖形方式顯示內容
  •   cell2mat:將數組轉變成為普通的矩陣
  •   mat2cell:將數值矩陣轉變成為cell數組
  •   num2cell:將數值數組轉變成為cell數組
  •   cell2struct:將數組轉變成為結構
  •   struct2cell:將結構轉變為cell數組
  •   iscell:判斷輸入是否為cell數組
  • cellfun:為cell數組的每個cell執行指定的函數 fun可以是特殊函數或者句柄
    1. days{1} = 'Sunday';    days{2} = 'Monday';
      days{3} = 'Tuesday';   days{4} = 'Wednesday';
      days{5} = 'Thursday';  days{6} = 'Friday';
      days{7} = 'Saturday';
      shortNames = cellfun(@(x)x(1:3), days, 'UniformOutput', false)
      shortNames = 
          '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 };
    [nrows,ncols]= size(mycell);
    filename = 'celldata.dat';
    fid = fopen(filename, 'w');
    for row=1:nrows
        fprintf(fid, '%s %d %d %d\n', mycell{row,:});
    end
    fclose(fid);

     

僅有數值時候 可以考慮先cell2mat 然后csvwrite.
cellfun的例子可以參考Matlab公司的http://www.mathworks.cn/support/solutions/en/data/1-1190ZB/index.html?solution=1-1190ZB


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM