Skip to content

MATLAB - 单元格数组

单元格数组(cell array)是 MATLAB 中一种基本的数据类型,它作为一种灵活的容器。与必须容纳相同类型元素(例如,全部为 double 或全部为 char)的标准数值数组不同,单元格数组可以在其单独的单元格中存储不同类型和大小的项的集合。

将常规数组想象成一盒鸡蛋(所有元素都相同),而单元格数组则像一个便当盒或工具箱,每个隔间可以存放完全不同的东西:一个数字、一段文本、另一个数组,甚至另一个单元格数组。

尽管功能强大,但单元格数组并非总是最佳选择。现代 MATLAB 提供了通常更高效、更便捷的专门数据类型。以下是何时使用何种类型数据的快速指南:

数据类型最佳用途示例
数值数组同构数值数据(矩阵、向量)。所有数学运算。[1, 2, 3; 4, 5, 6]
字符串数组同构文本数据。提供丰富的文本操作函数。["Apple", "Banana", "Cherry"]
表异构但结构化(列式)的数据,例如电子表格。列可以有不同的类型,但长度都相同。table(Name, Age, Score)
结构体在命名字段下存储不同数据类型的集合,表示单个对象。patient.name = "John"; patient.age = 45;
单元格数组存储非结构化或参差不齐的异构数据集合。常用于大小或类型可变的函数输出。{'Hello', [1 2; 3 4], magic(5)}

您可以使用花括号 {} 进行直接构造或使用 cell() 函数进行预分配来创建单元格数组。

使用花括号 {} 括住您的数据集合。使用分号 ; 开始新行。

% 一个 1x3 单元格数组
myCells = { 'This is a character array', [10 20 30], true };
% 一个 2x2 单元格数组
dataLog = { "Experiment A", [1.5, 2.3, 2.1]; ...
"Experiment B", [0.8, 0.9, 0.85] };
disp(dataLog);

关键概念:使用 () 与 {} 进行索引

Section titled “关键概念:使用 () 与 {} 进行索引”

这是 MATLAB 新用户最常见的混淆点。理解括号和花括号在索引方面的区别是关键。

  • 小括号 ():访问单元格(容器本身)。这会返回一个包含指定单元格的新单元格数组。这就像从便当盒中取出一个隔间,但保持其关闭。
  • 花括号 {}:访问内容(内部的数据)。这会提取单元格内部的实际数据。这就像打开隔间并取出食物。
dataLog = { "Experiment A", [1.5, 2.3, 2.1]; ...
"Experiment B", [0.8, 0.9, 0.85] };
% --- 使用小括号 () ---
cellSubset = dataLog(1, :); % 获取第一行
disp('使用 (): 返回一个 1x2 单元格数组')
disp(cellSubset);
% 您不能对 cellSubset 进行数学运算,例如 cellSubset(1,2) + 1 -> 错误
% --- 使用花括号 {} ---
content = dataLog{1, 2}; % 提取 (1,2) 处单元格的内容
disp('使用 {}: 返回单元格内的数值向量')
disp(content);
% 您可以对内容进行数学运算
meanValue = mean(content);
disp(['数据的平均值: ', num2str(meanValue)]);

为了性能,尤其是在循环中,最佳实践是为您的数组预分配内存。cell() 函数会创建一个指定大小的单元格数组,并用空矩阵填充。

% 预分配一个 10x3 单元格数组
results = cell(10, 3);
% 在循环中填充数组
for i = 1:10
results{i, 1} = sprintf("Run %d", i); % 第 1 列的内容:一个字符串
results{i, 2} = rand(1, i); % 第 2 列的内容:一个大小变化的随机向量
results{i, 3} = rand() > 0.5; % 第 3 列的内容:一个逻辑值
end
disp('预分配单元格数组的前 3 行:');
disp(results(1:3, :));

MATLAB 提供了将其他数据类型转换为单元格数组的函数,这对于与旧函数兼容或执行特定数据操作任务非常有用。

num2cell(): 数值数组到单元格数组

Section titled “num2cell(): 数值数组到单元格数组”

将数值数组转换为单元格数组。数值数组的每个元素都将成为单元格的内容。

numericMatrix = [1 2; 3 4];
cellMatrix = num2cell(numericMatrix);
% cellMatrix 现在是一个 2x2 的单元格数组,其中 cellMatrix{1,1} 包含 1,以此类推。

将表转换为单元格数组。请谨慎使用此功能。 将表转换为单元格数组会丢失宝贵的列名和元数据。通常最好直接使用表。此转换主要用于与不接受表作为输入的旧函数进行接口。

% 创建一个现代表
Name = ["Riya"; "Siya"; "Tiya"];
Age = [25; 30; 28];
Height = [160; 175; 168];
Weight = [55; 70; 65];
dataTable = table(Name, Age, Height, Weight);
% 转换为单元格数组(丢失列名)
cellData = table2cell(dataTable);
disp('原始表:');
disp(dataTable);
disp('转换后的单元格数组:');
disp(cellData);
  • 索引混淆: 最常见的错误是混淆 () 和 {}。如果您收到类似“对 ‘cell’ 类型的输入参数未定义函数 ‘plus’”的错误,则很可能是在需要 {} 的地方使用了 ()。
  • 性能: MATLAB 数组是动态增长的,但这效率低下。在循环中填充单元格数组之前,务必使用 cell(rows, cols) 进行预分配。
  • 选择合适的工具: 不要默认使用单元格数组。如果您的数据是表格形式的,请使用 table。如果是一系列字符串,请使用 string 数组。仅当数据确实是非结构化、混合类型时才使用单元格数组。