【问题标题】:Efficient allocation of cell array in matlabmatlab中单元格数组的高效分配
【发布时间】:2014-11-26 15:34:23
【问题描述】:

我有一些可以将字符串元胞数组转换为字符元胞数组。

注意。由于多种原因,输入 (C) 和输出 (C_itemised) 都必须是元胞数组。

字符串元胞数组(C)如下:

>> C(1:10)

ans = 

't1416933446'
''
't1416933446'
''
't1416933446'
''
't1416933446'
''
't1416933446'
''

我在这里只展示了数组的一部分。实际上,它的长度约为 28,000 行。

我有一些代码可以做到这一点,尽管它效率很低。 cellstr 函数占用了 72% 的代码时间,因为它目前被调用了数千次。代码如下:

C_itemised=cell(length(C),500);
for i=3:length(C)
    temp=char(C{i});

    for j=1:length(temp)
        C(i-2,j)=cellstr(temp(j));
    end
end

我感觉一些小的修改可以去掉内部循环,从而大大减少整体运行时间。我已经尝试了很多方法来做到这一点,但我想我一直对是否使用 {} 或 () 感到困惑,并且无法在网上找到任何可以帮助我的东西。任何人都可以找到使代码更高效的方法吗?

还请注意,此功能与其他功能结合使用,并且确实有效,尽管它的运行速度比理想情况下要慢。因此,我不想改变C_itemised的格式。

编辑: (示例)我当前函数的输出是:

C_itemised(1,1:12)

ans = 

Columns 1 through 12

't'    '1'    '4'    '1'    '6'    '9'    '3'    '3'    '4'    '4'    '6'    []

【问题讨论】:

  • 所以你有一个字符串元胞数组。您的目标是获取每个字符串,并将其转换为字符元胞数组,其中该元胞数组中的每个元素都是一个单独的字符吗?
  • 是的,每一行都包含原始数组中同一行的各个字符

标签: arrays matlab performance cell-array


【解决方案1】:

我可以建议的一件事是使用未记录的函数sprintfc。此函数在 MATLAB 中无法正常使用,但在内部与各种其他函数一起使用。主要是,如果你尝试做help sprintfc,它会说没有找到函数!有时嗅探源头很酷!

sprintfc 的工作原理是为它提供一个格式字符串,就像printf 一样,以及您要打印的数据。它将获取数据中的每个单独元素并将它们放入单独的单元格数组中。例如,假设我有一个字符串D = 'abcdefg';,如果我们这样做:

out = sprintfc('%c', D);

我们得到:

>> celldisp(out)

out{1} =

a


out{2} =

b


out{3} =

c


out{4} =

d


out{5} =

e


out{6} =

f


out{7} =

g

因此,它获取字符串中的每个元素并将它们作为单独的字符放置在新的元胞数组中作为单独的元素。 %c 格式化字符串意味着我们要为每个元素打印一个字符。如果您想了解更多信息,请查看我在上面发布的 Undocumented MATLAB 的链接!


因此,请尝试将循环简化为:

C_itemised=cell(length(C));
for i=1:length(C)
    C_itemised{i} = sprintfc('%c', C{i});
end

C_itemised 将是一个元胞数组,其中每个元素 C_itemised{i} 是另一个元胞数组,该元胞数组中的每个元素都是由字符串 C{i} 组成的单个字符。


小提示

您说您对 MATLAB 中用于单元格的 {} 和 () 感到困惑。 {} 用于访问单元格内的各个元素。因此,例如 C{1} 将抓取存储在单元格数组的第一个元素中的任何内容。 () 用于对单元格进行切片和索引。例如,如果您想创建另一个元胞数组,它是当前元胞数组的子集,您可以执行C(1:3) 之类的操作。这将创建一个三元素元胞数组,该数组由C 中的前三个元胞组成。

【讨论】:

  • 这段代码看起来不错,虽然我现在运行它时内存不足。
  • @Doragan - 每个字符串有多少个字符?如果每个字符串平均有大约 1000 个字符,并且有 28000 行,那么您可能会很快耗尽内存。这并不能解释为什么您的其他代码可以工作。在再次运行代码之前尝试执行clear all;?另外,如果您不打算再次使用C,请考虑在循环中使用nulling 每个条目,在循环结束时使用C{i} = [];。
  • 很酷的功能!保存以备后用。
  • @rayryeng 字符数一般约为 40。我很困惑为什么我的内存也用完了,并尝试在单行上使用它,但遇到了同样的问题,所以它似乎不是因为 C 数组很大。我也尝试重新启动 Matlab。明天重启机器后我会重试代码,并会告诉你。 sprintfc 函数看起来确实很有用。
  • @Doragan - 这很奇怪......好吧!告诉我进展如何!
猜你喜欢
  • 2013-07-25
  • 2013-08-19
  • 1970-01-01
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 2016-08-30
  • 2018-11-16
  • 2012-12-31
相关资源
最近更新 更多