前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >matlab 单元数组和元胞数组

matlab 单元数组和元胞数组

作者头像
演化计算与人工智能
发布2020-08-14 00:04:40
1.7K0
发布2020-08-14 00:04:40
举报

本文为matlab自学笔记的一部分,之所以学习matlab是因为其真的是人工智能无论是神经网络还是智能计算中日常使用的,非常重要的软件。也许最近其带来的一些负面消息对国内各个高校和业界影响很大。但是我们作为技术人员,更是要奋发努力,拼搏上进,学好技术,才能师夷长技以制夷,为中华之崛起而读书!

本文很多摘录自图书资料,不做任何商业用途,仅做技术分享,侵权删除!请不要放弃自己的理想和道路,加油!!

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列中的元素内容
代码语言:javascript
复制
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函数复制单元数组

代码语言:javascript
复制
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--显示单元数组的所有单元内容

代码语言:javascript
复制
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--判断是否为元胞数组

代码语言:javascript
复制
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--确定变量是否具有指定的数据类型

代码语言:javascript
复制
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 指定的输入参数的数量相同。

将函数应用于元胞数组的内容

代码语言:javascript
复制
创建一个元胞数组,其中包含不同大小的数值数组。

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

将函数应用于元胞数组的内容

代码语言:javascript
复制
创建两个元胞数组,其中包含不同大小的数值数组。

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

返回多个输出数组

代码语言:javascript
复制
创建一个元胞数组,其中包含不同大小的数值数组。

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 以相同的方式处理这两种数组。创建一个字符向量元胞数组,其中包含一周各个工作日的名称。
代码语言:javascript
复制
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 整个数组。

将数组转换为元胞数组

代码语言:javascript
复制
  将一个数值数组的所有元素放入单独的元胞。

  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 的元胞数组。
代码语言:javascript
复制
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
  • 按列划分
代码语言:javascript
复制
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
  • 按行划分
代码语言:javascript
复制
创建 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
  • 按第三个维度进行划分
代码语言:javascript
复制
创建 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

合并维度

  • 通过合并各个维度的数值数组创建一个元胞数组
代码语言:javascript
复制
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}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DrawSky 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • cell array --cell,celldisp,iscell,isa,deal,cellfun,num2cell,size
  • 单元数组的创建和操作
  • 高维数组取值区别
    • 使用repmat函数复制单元数组
    • 单元数组函数
      • cell--新建元胞数组
        • celldisp--显示单元数组的所有单元内容
          • iscell--判断是否为元胞数组
            • isa--确定变量是否具有指定的数据类型
              • cellfun--将一个指定的函数应用到一个单元数组的所有单元
                • 语法
                • 说明
                • 将函数应用于元胞数组的内容
                • 将函数应用于元胞数组的内容
                • 返回多个输出数组
                • 将函数应用于元胞数组或字符串数组中的字符
              • size--获取数组的维度大小数值
                • num2cell--从一个数组中提取指定元素,填充到单元数组
                  • 语法
                  • 说明
                  • 将数组转换为元胞数组
                  • 创建数值数组的元胞数组
                  • 合并维度
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档