【问题标题】:Logical tests on Cell Arrays元胞阵列的逻辑测试
【发布时间】:2016-03-18 16:08:02
【问题描述】:

在 Matlab 中处理常规数组时,可以很容易地执行逻辑测试并将这些测试失败的单元格设置为所需的值,例如 NaN,而无需使用 for 循环。

TestA=[1 2 10 45];
TestA(TestA<=2)=NaN;

我有一个单元格数组,我可以在其中进行逻辑测试 OK,但是如何在不使用 for 循环的情况下将测试失败的单元格数组元素转换为 NaN?

TestCell{1}=[1 2 10 45];
TA=TestCell{1} <= 2;

谢谢

巴兹

【问题讨论】:

  • 避免循环的原因是什么?

标签: matlab cell-array


【解决方案1】:

如果元胞数组元素是数值数组,同样的概念也适用。

TestCell{1}(TestCell{1} <= 2) = NaN;

现在,如果您想在没有显式 for 循环的情况下遍历单元格的 所有 元素,这有点困难,因为您无法在 cellfun 内进行赋值。

另一种方法是构造一些表达式,当您的条件为真时,该表达式将返回一个数组,其中存在 NaN,其他地方的原始值。

这样的表达式可能如下所示:

x .* ~(x <= 2) ./ ~(x <= 2);

这将导致每个元素在条件为真时乘以0/0 (NaN),在条件为假时乘以1/1 (1)。这样,所有满足条件的值都会被设置为 NaNs。

如果我们在您的示例数据上尝试此操作:

x = [1 2 10 45];
x .* ~(x <= 2) ./ ~(x <= 2)

    NaN   NaN    10    45

我们得到你的条件为真的 NaN。所以现在我们可以将其插入cellfun 以对所有内容执行此操作。

output = cellfun(@(x)x .* ~(x <= 2)./~(x <= 2), TestCell, 'uni', 0);

另一种方法是将条件倒写,这样所有符合条件的元素都将设置为NaN。这将避免必须否定上述等式中的两个条件。

x = [1 2 10 45]
x .* (x > 2) ./ (x > 2)

我们可以像上面那样将它插入cellfun

output = cellfun(@(x)x .* (x > 2) ./ (x > 2), TestCell, 'uni', 0);

这种方法的主要缺点是它需要您评估条件两次,因为没有很好的方法将中间结果存储在cellfun 中。这可能是也可能不是问题,具体取决于每个元素的大小。有一个 for 循环来做这种事情真的没有什么可耻的,因为它可能比这里的解决方案性能更高。

【讨论】:

  • 这不是对 MATLAB 自卫的一种破解吗?与普通数组不同,元胞数组可以包含不同类型的元素。对相同类型的元素进行操作时,无需使用元胞数组。
  • @Crowley 可能是相同类型但不同维度的元素。
  • 如果你把向量或字符串作为类型你是对的。但字符串是char 的数组,向量是double 的数组。
  • @Crowley 我指的是这种情况。 C = {[1,2,3], [1,2]}
  • @Crowley 我有点困惑你想在这里指出什么。从技术上讲all variables are arrays,甚至是双标量。无论如何,我在上面发布的示例是使用元胞数组存储双精度的多元素数组的完全正当理由。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-30
  • 2012-02-05
  • 1970-01-01
  • 2019-05-30
相关资源
最近更新 更多