matlab學習筆記12_1單元數組和元胞數組 cell,celldisp,iscell,isa,deal,cellfun,num2cell,size


一起來學matlab-matlab學習筆記12

12_1 單元數組和元胞數組

cell array --cell,celldisp,iscell,isa,deal,cellfun,num2cell,size

覺得有用的話,歡迎一起討論相互學習~

我的微博我的github我的B站

  • 單元數組(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}


免責聲明!

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



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