原文地址: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可以是特殊函數或者句柄
-
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幫助里面的循環例子:
-
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中支持甚多,因此也就常用了.功能偏弱,但是基本按照規則,還是可以盡量減少出錯的.
希望大家也交換一下使用的心得~
