使用逻辑矩阵选择单元格的元素

Selecting elements of a cell using a logical matrix

假设我有一个像这样的空元胞数组:

dim = [100,200];

x = cell(dim);

我想用'a'(字符串)替换x的对角线元素。这就是我所做的:

mask = logical(eye(dim));
x{mask} = {'a'};

但是,我收到以下错误:

The right hand side of this assignment has too few values to satisfy the left hand side

Error in test (line 28)

x{mask} = {'a'};

我也试过:

mask_2 = find(mask == true);
x{mask_2} = {'a'};

但我得到了同样的错误。有什么办法可以解决这个问题吗?我希望脚本尽可能高效。

要引用一组单元格,请使用 Matlab 文档中所说的 "smooth parentheses",或者我们所说的普通括号:

http://www.mathworks.com/help/matlab/matlab_prog/access-data-in-a-cell-array.html

x(mask) = {'a'}

dim = [5,6] 的结果:

x =
{
  [1,1] = a
  [2,1] = [](0x0)
  [3,1] = [](0x0)
  [4,1] = [](0x0)
  [5,1] = [](0x0)
  [1,2] = [](0x0)
  [2,2] = a
  [3,2] = [](0x0)
  [4,2] = [](0x0)
  [5,2] = [](0x0)
  [1,3] = [](0x0)
  [2,3] = [](0x0)
  [3,3] = a
  [4,3] = [](0x0)
  [5,3] = [](0x0)
  [1,4] = [](0x0)
  [2,4] = [](0x0)
  [3,4] = [](0x0)
  [4,4] = a
  [5,4] = [](0x0)
  [1,5] = [](0x0)
  [2,5] = [](0x0)
  [3,5] = [](0x0)
  [4,5] = [](0x0)
  [5,5] = a
  [1,6] = [](0x0)
  [2,6] = [](0x0)
  [3,6] = [](0x0)
  [4,6] = [](0x0)
  [5,6] = [](0x0)
}

我知道有两种方法可以做到这一点。

第一种是用圆括号代替方括号来寻址。这 return 是每个地址的元胞数组引用,因此您必须为结果分配一个元胞数组:

x(mask) = {'a'};

第二种是使用括号寻址,这将return一个逗号分隔的列表。那是什么?您从未听说过 Matlab 中的 comma-separated list 吗?那是因为它是 Matlab 中了解最少的数据类型,尽管我向您保证您以前见过它。阅读 link 了解更多信息。我发现很多 Matlab 的 "weirdness" 在我理解逗号分隔列表是什么以及它们的使用位置后变得更有意义。

无论如何,如果您尝试编写 x{mask} = 'a',它不会起作用,因为您正试图将单个值分配给以逗号分隔的引用列表。您可以使用 deal 函数通过巧妙地连接引用来分配给每个引用:

[x{mask}] = deal('a');

好了。使用逻辑索引分配给元胞数组的两种方法。我不确定哪个更快,你必须自己测试一下。

除了此处给出的解释之外,您还可以避免创建(可能很大的)逻辑数组,如果这是它的唯一目的,并使用 linear indexing to assign the values directly using the sub2ind 函数:

dim = [100,200];
x = cell(dim);
x(sub2ind(dim,1:dim(1),1:dim(1))) = {'a'};

如评论中所述,sub2ind 函数很容易在这里回避,因为对角线元素之间的步幅是一个常数值(行数)。所以上面可以简化为

x(1:dim(1)+1:dim(1)^2) = {'a'};

另一个选项(一个班轮,我最喜欢的解决方案),使用问题中提出的逻辑(eye 函数等):

x=num2cell(char(eye(n,m)*97),n)

其中 dim=[n,m]97 将编码字符串 'a'...