一起來學matlab-matlab學習筆記12
12_1 單元數組和元胞數組
cell array --cell,celldisp,iscell,isa,deal,cellfun,num2cell,size
覺得有用的話,歡迎一起討論相互學習~
- 單元數組(cellarray)和結構體(structure)都可以將不同類型的相關數據集成到一個單一的變量中,使得大量的相關數據的處理變得非常簡單而且方便。但是,需要注意的是,單元數組和結構體只是承載其他數據類型的容器,大部分的數學運算則只是針對兩者之中具體的數據進行,而不是針對單元數組或結構體本身而進行。
- 單元數組中的每一個單元是通過一個數字來進行索引的,但用戶需要加人一個單元中或者從一個單元中提取數據時,需要給出單元數組中該單元的索引。結構體和單元數組十分相似,兩者之間的主要區別在於,結構體中的數據存儲並不是由數字來表示的,而是通過結構體中的名稱來進行表示的。
單元數組的創建和操作
- 單元數組中的每一個元素稱為單元(cell)。單元中的數據可以為任何數據類型,包括數值數組、字符、符號對象、其他單元數組或結構體等。不同的單元中的數據類型可以不同。理論上,單元數組可以創建任意維數的單元數組,大多數情況下,為簡單起見,創建簡單的單元數組(如一維單元數組)。單元數組的創建方法可以分為兩種,通過賦值語句直接創建;或通過cell函數首先為單元數組分配內存空間,然后再對每個單元進行賦值。如果在工作空間內的某個變量名與所創建的單元數組同名,那么此時則不會對單元數組賦值
- 直接通過賦值語句創建單元數組時,可以采用兩種方法來進行,即按 單元索引法 和按 內容索引法(其實也就是將花括號放在等式的右邊或是左邊的區別)。按 單元索引法 賦值時,采用標准數組的賦值方法,賦值時賦給單元的數值通過花括號 ({}) 將單元內容括起來。按 內容索引法 賦值時,將花括號寫在等號左邊,即放在單元數組名稱后。
- 注意."按單元索引法"和"按內容索引法"是完全等效的,可以互換使用。通過上面的實例,我們看到:花括號"{}"用於訪問單元的值,而括號"()"用於標識單元(即:不用於訪問單元的值)。具體理解"{}"和"()"區別可以在下面代碼最后分別輸入A{2,2}和A(2,2)。就會發現."按內容索引法{}"能顯示完整的單元內容,而"按單元索引法()"有時無法顯示完整的單元內容。如果需要將單元數組的所有內容都顯示出來,則可以采用celldisp函數來強制顯示單元數組的所有內容。
- 單元數組創建的另一種方法是通過cell函數進行創建的。在創建時,可以采用cell函數生成空的單元數組,為單元數組分配內存,然后再想單元數組內存儲內容。存儲數據時,可以采用 內容賦值法 或采用 單元索引法 來進行
- 單元數組還可以通過擴展的方法來得到進一步的擴展。如利用方括號將多個單元數組組合在一起,從而形成維數更高的單元數組。如果想要獲得單元數組子單元的內容,則可以利用數組索引的方法,將一個數組的子集提取出賦予新的單元數組。刪除單元數組中的某一部分內容,可以將這部分內容設置為空數組,即可刪除單元數組中的這部分內容
高維數組取值區別
- 對於其他語言來說,往往使用多個方括號的形式[][],來對高維數組中的元素進行取值,但是在matlab中使用","分隔維度.例如A(3,1)表示取A數組中第三行第一個元素,A(3,:)表示取第三行所有列的元素,A([1,2],:)表示取第一行和第二行所有列中的元素
- 對於元胞數組的拼接使用的是"[]"方括號,而不是"{}或者是()",但是使用數組的數組和搜索使用"{}"比"()"更好, 例如a(1,1)返回的是1行1列元素的數據類型,a{1,1}返回的是1行1列中的元素內容
clear A %按單元索引法賦值
A(1,1)={[1 2 3;4 5 6; 7 8 9]};
A(1,2)={1+2i};
A(2,1)={'hello world'};
A(2,2)={0:pi/3:pi};
clear B %按內容索引法賦值
B{1,1}=[1 2 3;4 5 6;7 8 9];
B{1,2}=3+4i;
B{2,1}='hello world';
B{2,2}=0:2:9;
% 使用B(2,:)可以提取B cell array中第二行中所有的元素,:表示取所有的列
C=[A;B] % 將A元胞數組中的所有元素和B元胞數組中的所有元素相拼接
sprintf('C(i)表示遍歷C數組中的所有個體元素')
for i =1:8
C{i}
end
sprintf('C(3,1)')
sprintf('%f',C{3,1}) % 表示取第三行的第一個元素
sprintf('C(i,:)表示遍歷C數組中的所有行元素')
for i=1:4
C{i,:}
end
% sprintf('C(3,1) %f',C(3,1)) % 表示取第三行的第一個元素 這是一種錯誤的寫法,這種寫法會報錯誤
C =
[3x3 double] [1.0000 + 2.0000i]
'hello world' [1x4 double]
[3x3 double] [3.0000 + 4.0000i]
'hello world' [1x5 double]
ans =
C(i)表示遍歷C數組中的所有個體元素
ans =
1 2 3
4 5 6
7 8 9
ans =
hello world
ans =
1 2 3
4 5 6
7 8 9
ans =
hello world
ans =
1.0000 + 2.0000i
ans =
0 1.0472 2.0944 3.1416
ans =
3.0000 + 4.0000i
ans =
0 2 4 6 8
ans =
C(3,1)
ans =
1.0000004.0000007.0000002.0000005.0000008.0000003.0000006.0000009.000000
ans =
C(i,:)表示遍歷C數組中的所有行元素
ans =
1 2 3
4 5 6
7 8 9
ans =
1.0000 + 2.0000i
ans =
hello world
ans =
0 1.0472 2.0944 3.1416
ans =
1 2 3
4 5 6
7 8 9
ans =
3.0000 + 4.0000i
ans =
hello world
ans =
0 2 4 6 8
- 在單元數組的操作中,可以利用reshape函數來改變單元數組的結構。經過reshape函數對單元數組進行處理后,單元數組的內容並不會增加或減少,且單元數組改變前后的單元總數目並不發生變化。
使用repmat函數復制單元數組
format compact
A1=cell(1)
A2=cell(2)
A3=cell(3) % 默認初始化為方陣
A=cell(2,3)
size(A)%計算單元數組A的大小
B=reshape(A,3,2)%改變結構后的單元數組
C1=repmat(B,1,2)
C2=repmat(B,3,2)
A1 =
{[]}
A2 =
[] []
[] []
A3 =
[] [] []
[] [] []
[] [] []
A =
[] [] []
[] [] []
ans =
2 3
B =
[] []
[] []
[] []
C1 =
[] [] [] []
[] [] [] []
[] [] [] []
C2 =
[] [] [] []
[] [] [] []
[] [] [] []
[] [] [] []
[] [] [] []
[] [] [] []
[] [] [] []
[] [] [] []
[] [] [] []
單元數組函數
- MATLAB提供了單元數組的處理函數
cell--新建元胞數組
celldisp--顯示單元數組的所有單元內容
a=ones(3,4);
b=zeros(3,2);
c=(5:6)';
X={a b c}
celldisp(X)
X =
[3x4 double] [3x2 double] [2x1 double]
X{1} =
1 1 1 1
1 1 1 1
1 1 1 1
X{2} =
0 0
0 0
0 0
X{3} =
5
6
iscell--判斷是否為元胞數組
a=ones(3,4);
b=zeros(3,2);
c=(5:6)';
X={a b c};
% celldisp(X);
iscell(a)
iscell(X)
ans =
0
ans =
1
isa--確定變量是否具有指定的數據類型
A = 3.1416;
tf1 = isa(A,'double')
tf2 = isa(A,'int')
tf1 =
1
tf2 =
0
cellfun--將一個指定的函數應用到一個單元數組的所有單元
- 對元胞數組中的每個元胞應用數組
語法
A = cellfun(func,C)
A = cellfun(func,C1,...,Cn)
A = cellfun( ___ ,Name,Value )
[ A1,...,Am ] = cellfun( ___ )
說明
- A = cellfun(func,C) 將函數 func 應用於元胞數組 C 的每個元胞的內容,每次應用於一個元胞。然后 cellfun 將 func 的輸出串聯成輸出數組 A,因此,對於 C 的第 i 個元素來說,A(i) = func(C{i})。輸入參數 func 是一個函數的函數句柄,此函數接受一個輸入參數並返回一個標量。func 的輸出可以是任何數據類型,只要該類型的對象可以串聯即可。數組 A 和元胞數組 C 具有相同的大小。
您不能指定 cellfun 計算 A 的各元素的順序,也不能指望它們按任何特定的順序完成計算。
-
A = cellfun(func,C1,...,Cn) 將 func 應用於 C1,...,Cn 的各元胞的內容,因此 A(i) = func(C1{i},...,Cn{i})。函數 func 必須接受 n 個輸入參數並返回一個標量。元胞數組 C1,...,Cn 的大小必須全部相同
-
A = cellfun ( ___ ,Name,Value ) 應用 func 並使用一個或多個 Name,Value 對組參數指定其他選項。例如,要以元胞數組形式返回輸出值,請指定 'UniformOutput',false。當 func 返回的值不能串聯成數組時,可以按元胞數組的形式返回 A。您可以將 Name,Value 對組參數與上述任何語法中的輸入參數結合使用。
-
當 func 返回 m 個輸出值時,[A1,...,Am] = cellfun( ___ ) 返回多個輸出數組 A1,...,Am。func 可以返回不同數據類型的輸出參數,但每次調用 func 時返回的每個輸出的數據類型必須相同。您可以將此語法與前面語法中的任何輸入參數結合使用。從 func 返回的輸出參數的數量不必與 C1,...,Cn 指定的輸入參數的數量相同。
將函數應用於元胞數組的內容
創建一個元胞數組,其中包含不同大小的數值數組。
C = {1:10, [2; 4; 6], []}
C = 1x3 cell array
{1x10 double} {3x1 double} {0x0 double}
計算每個數值數組的均值,然后以數組的形式返回這些均值。
A = cellfun(@mean,C)
A = 1×3
5.5000 4.0000 NaN
將函數應用於元胞數組的內容
創建兩個元胞數組,其中包含不同大小的數值數組。
X = {5:5:100, 10:10:100, 20:20:100};
Y = {rand(1,20), rand(1,10), rand(1,5)};
繪制數組。從 plot 函數返回圖形線條對象數組,並使用這些對象為每一組數據點添加不同的標記。cellfun 可以返回任何數據類型的數組,只要該數據類型的對象可以串聯即可。
figure
hold on
p = cellfun(@plot,X,Y);
p(1).Marker = 'o';
p(2).Marker = '+';
p(3).Marker = 's';
hold off
返回多個輸出數組
創建一個元胞數組,其中包含不同大小的數值數組。
C = {1:10, [2; 4; 6], []}
C = 1x3 cell array
{1x10 double} {3x1 double} {0x0 double}
計算 C 中每個數組的大小。行數和列數分別輸出在兩個 1×3 數值數組中。
[nrows,ncols] = cellfun(@size,C)
nrows = 1×3
1 3 0
ncols = 1×3
10 1 0
將函數應用於元胞數組或字符串數組中的字符
- 您可以使用 cellfun 將函數應用於字符向量元胞數組和字符串數組。cellfun 以相同的方式處理這兩種數組。
創建一個字符向量元胞數組,其中包含一周各個工作日的名稱。
C = {'Monday','Tuesday','Wednesday','Thursday','Friday'}
C = 1x5 cell array
{'Monday'} {'Tuesday'} {'Wednesday'} {'Thursday'} {'Friday'}
使用 cellfun 函數為這些名稱創建三個字母的縮寫。指定一個函數,以提取前三個字符並將它們以字符向量的形式返回。要以元胞數組的形式返回這些縮寫,請指定 'UniformOutput',false 名稱-值對組。
A = cellfun(@(x) x(1:3),C,'UniformOutput',false)
A = 1x5 cell array
{'Mon'} {'Tue'} {'Wed'} {'Thu'} {'Fri'}
為了實現兼容性,cellfun 將字符串數組的每個元素視為一個字符向量。如果您指定返回文本的函數,cellfun 將以字符向量元胞數組而不是字符串數組的形式返回文本。 " 'UniformOutput',false "
使用 cellfun 為字符串數組中的名稱創建縮寫。
str = ["Saturday","Sunday"]
str = 1x2 string array
"Saturday" "Sunday"
B = cellfun(@(x) x(1:3),str,'UniformOutput',false)
B = 1x2 cell array
{'Sat'} {'Sun'}
size--獲取數組的維度大小數值
num2cell--從一個數組中提取指定元素,填充到單元數組
- 將數組轉換為相同大小的元胞數組
語法
C = num2cell(A)
C = num2cell(A,dim)
說明
- C = num2cell(A) 通過將 A 的每個元素放置於 C 的一個單獨元胞中,來將數組 A 轉換為元胞數組 C。num2cell 函數轉換具有任意數據類型(甚至是非數值類型)的數組。
- C = num2cell(A,dim) 將 A 的內容划分成 C 中單獨的元胞,其中 dim 指定每個元胞包含 A 的哪個維度。dim 可以是維度的標量或向量。例如,如果 A 有 2 行 3 列,那么:
- num2cell(A,1) 創建一個 1×3 元胞數組 C,其中每個元胞包含 A 的 2×1 列。 即按列划分
- num2cell(A,2) 創建一個 2×1 元胞數組 C,其中每個元胞包含 A 的 1×3 行。 即按行划分
- num2cell(A,[1 2]) 創建一個 1×1 元胞數組 C,其中每個元胞包含 A 整個數組。
將數組轉換為元胞數組
將一個數值數組的所有元素放入單獨的元胞。
a = magic(3)
a = 3×3
8 1 6
3 5 7
4 9 2
c = num2cell(a)
c = 3x3 cell array
{[8]} {[1]} {[6]}
{[3]} {[5]} {[7]}
{[4]} {[9]} {[2]}
將一個單詞的各個字母放入數組的各個元胞中。
a = ['four';'five';'nine']
a = 3x4 char array
'four'
'five'
'nine'
c = num2cell(a)
c = 3x4 cell array
{'f'} {'o'} {'u'} {'r'}
{'f'} {'i'} {'v'} {'e'}
{'n'} {'i'} {'n'} {'e'}
創建數值數組的元胞數組
- 生成一個 4×3×2 的數值數組,然后創建一個包含 4×1 列向量的 1×3×2 的元胞數組。
A = reshape(1:12,4,3);
A(:,:,2) = A*10
A =
A(:,:,1) =
1 5 9
2 6 10
3 7 11
4 8 12
A(:,:,2) =
10 50 90
20 60 100
30 70 110
40 80 120
- 按列划分
C = num2cell(A,1)
C = 1x3x2 cell array
C(:,:,1) =
{4x1 double} {4x1 double} {4x1 double}
C(:,:,2) =
{4x1 double} {4x1 double} {4x1 double}
每個 4×1 向量包含沿 A 的第一維度的元素:
C{1}
ans = 4×1
1
2
3
4
- 按行划分
創建 1×3 數值數組的 4×1×2 元胞數組。
C = num2cell(A,2)
C = 4x1x2 cell array
C(:,:,1) =
{1x3 double}
{1x3 double}
{1x3 double}
{1x3 double}
C(:,:,2) =
{1x3 double}
{1x3 double}
{1x3 double}
{1x3 double}
每個 1×3 行向量包含沿 A 的第二維度的元素:
C{1}
ans = 1×3
1 5 9
- 按第三個維度進行划分
創建 1×1×2 數值數組的 4×3 元胞數組。
C = num2cell(A,3)
C = 4x3 cell array
{1x1x2 double} {1x1x2 double} {1x1x2 double}
{1x1x2 double} {1x1x2 double} {1x1x2 double}
{1x1x2 double} {1x1x2 double} {1x1x2 double}
{1x1x2 double} {1x1x2 double} {1x1x2 double}
每個 1×1×2 向量包含沿 A 的第三維度的元素:
C{1}
ans =
ans(:,:,1) =
1
ans(:,:,2) =
10
合並維度
- 通過合並各個維度的數值數組創建一個元胞數組
A = reshape(1:12,4,3);
A(:,:,2) = A*10
A =
A(:,:,1) =
1 5 9
2 6 10
3 7 11
4 8 12
A(:,:,2) =
10 50 90
20 60 100
30 70 110
40 80 120
c = num2cell(A,[1 3])
c = 1x3 cell array
{4x1x2 double} {4x1x2 double} {4x1x2 double}
每個 4×1×2 數組包含沿 A 的第一維度和第三維度的元素:
c{1}
ans =
ans(:,:,1) =
1
2
3
4
ans(:,:,2) =
10
20
30
40
c = num2cell(A,[2 3])
c = 4x1 cell array
{1x3x2 double}
{1x3x2 double}
{1x3x2 double}
{1x3x2 double}