matlab 高效地将结构体字段转换为数组

问题描述

我在 Matlab 中有一个名为 s 的结构。这是一个包含两个字段 ab 的结构。结构尺寸为 1 x 1,620,000。

这是一个非常大的结构(可能需要我机器的一半内存)。这是结构的样子:

enter image description here

我正在寻找一种有效的方法来将每个字段 ab 连接成两个单独的数组,然后我可以将它们导出到 csv。为此,我构建了下面的代码,但即使在运行 12 小时后,它甚至还没有达到循环的四分之一。有没有更有效的方法

a = [];
b =[];
total_n = size(s,2);
count = 1;
while size(s,2)>0

    if size(s(1).a,1)
    a =   [a; s(1).a];
    end
    if size(s(1).b,1)
    b =   [b; s(1).b];
    end
    s(1) = []; %to save memory
    if mod(count,1000) == 0
        fprintf('Done %2f  \n',[count/total_n])
    end
    count = count+1;
end

解决方法

s(1) = []; %to save memory

啊,但是评论是这么大的误解。

如果 size(s) 是 1 x 1,620,000,您只是突然强制循环执行(在引擎盖下,您看不到它)

snew=zeros(1,size(s,2)-1) # now you use double memory
snew=s(2:end)  # now you force an unnecesary copy

因此,该行不仅使您的代码需要双倍的内存,而且在每个循环中,您都会创建一个大数组的不必要副本。

只需将您的 while 替换为普通的 for ii=1:size(s,2) 循环,然后索引 s

现在,您可以满怀希望地看到为什么以下同样是一个大错误(不仅如此,任何现代 MATLAB 版本目前都告诉您这是编辑器中的一个坏主意)

a=[]
a=[a;s(1).a]

在这里,在每个循环中,您都在强制 MATLAB 创建一个比以前大 1 的新 a,并将旧 a 的内容复制到那里。 相反,预分配 a 的大小。

由于您不知道要在那里放什么,我建议使用元胞数组,因为每个 s(ii).a 都有不同的长度。

然后,您可以在循环之后,根据需要删除所有空 (isempty) 单元格。

,

设法有效地做到了:

s= struct2cell(s);
s= squeeze(s);
a = a(1,:);
a = a';
a = vertcat(a{:});
b = a(2,:);
b = b';
b = vertcat(b{:});

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...