matlab中cell陣列的全面介紹
阿新 • • 發佈:2019-01-26
本文轉載自: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陣列 ,{}是實際型別.結果顯示是一致的
- >> 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
- >>a(1)
- ans =
- 'a'
- >>a{1}
- ans =
- a
- >> a={'啊',123,[3 5 6],[1 2;7 8],sym(1)}
- 調整內容:因為a()表示一個cell,而a{}表示該cell中的內容,因此改變cell陣列中的內容時常用a{},如a{1}='cell',結果為
'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可以是特殊函式或者控制代碼
- 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'
- days{1} = 'Sunday'; days{2} = 'Monday';
- deal:將輸入引數賦值給輸出 [Y1, Y2, Y3, ...] = deal(X{:}) ->可以簡化[a,b,c,d] = C{:}
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幫助裡面的迴圈例子:
- 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);
cellfun的例子可以參考Matlab公司的http://www.mathworks.cn/support/solutions/en/data/1-1190ZB/index.html?solution=1-1190ZB
總結
基本是就是總結了一下用法,特別是轉換和儲存方面的,相對於struct陣列,由於Matlab中支援甚多,因此也就常用了.功能偏弱,但是基本按照規則,還是可以儘量減少出錯的.
希望大家也交換一下使用的心得~