我在MATLAB中有一个结构数组(98 * 1):
现在我试图通过使用2个特定字段(比如x和y)来绘制图形。 x和y的值存在于这98行中的每一行上。尝试使用以下命令绘制错误。
plot(ans{1:98,1}.x,ans{1:98,1}.y)
预期来自大括号或点索引表达式的一个输出,但是 有98个结果。
只是(第1行)图中的错误(ans {1:98,1} .x,ans {1:98,1} .y)
需要帮助知道我做错了什么,以及如何纠正它。
答案 0 :(得分:5)
你可以通过
做你想做的事S = [ans{:}];
x = [S.x];
y = [S.y];
plot(x,y)
第一行将单元格数组转换为结构数组。 ans{:}
返回单元格数组中所有元素的逗号分隔列表。方括号捕获,将所有元素连接到一个向量中。
S.x
再次返回以逗号分隔的列表。在这里,我们将所有x值连接到一个数字向量中。
但请,请更改您存储数据的方式。下面我将说明为什么你应该这样做。
让我们从类似于你的结构中的一些随机数据开始(每个元素都是结构的单元格数组):
C = cell(1,100);
for ii=1:length(C)
C{ii} = struct('x',randn(1),'y',randn(1),'z',randn(1),...
'name',char('a'+floor(rand(1,10)*('z'-'a'+1))),...
'status',rand(1)>0.3);
end
更好的解决方案是结构数组:
S = [C{:}];
结构数组是MATLAB中的标准事物:它是一个数组,其中每个元素都是相同的结构。你对这两者的索引有所不同:
>> C{5}
ans =
struct with fields:
x: -0.0818
y: 0.5463
z: -0.8194
name: 'ysrkqlzcms'
status: 1
>> S(5)
ans =
struct with fields:
x: -0.0818
y: 0.5463
z: -0.8194
name: 'ysrkqlzcms'
status: 1
为什么S
是比C
更好的解决方案?
>> whos
Name Size Bytes Class Attributes
C 1x100 103700 cell
S 1x100 60820 struct
请注意C
的占用率几乎是S
的两倍。为什么是这样? C
包含100个结构,每个结构存储一些值,但也包含这些值的名称。因此,C存储相同名称的100倍(在这种情况下,'x'
,'y'
,'z'
,'name'
和'status'
)。 S
只存储一次。
您需要发布此问题证明了这一点。我的答案的第一步是将单元格数组转换为结构数组。 Luis Mendo的回答显示了使用结构单元格数组是多么尴尬。
您可以执行C{5} = 'sorry'
,并阻止使用任何类型的方法来使用结构的所有x
元素,因为其中一个单元格不再是结构体。 S(5)='sorry'
给出错误。也就是说,没有办法强制结构的单元格数组中的所有结构都具有相同的元素。这使事情变得非常复杂。
由于MATLAB R2013b有一个table
类。类型table
的对象甚至比结构数组更好。
T = struct2table(S);
表将每列存储为单个数组,因此开销较少。也就是说,T.x
是一个单独的数组,而不是S.x
,它是100个数组。这使得它更有效率:
>> whos
Name Size Bytes Class Attributes
C 1x100 103700 cell
S 1x100 60820 struct
T 100x5 17476 table
请注意T
如何使用C
内存的1/6。这使得它也是类型安全的:每行的x
值保证是相同的类型和大小。如果将x
定义为标量双精度,则不能将字符串分配给一个x
值,也不能将任何非标量赋值。
再次建立索引略有不同,但T.x
直接为您提供了所有x
值的数组,并且
>> T(5,:)
ans =
1×5 table
x y z name status
_________ _______ ________ ____________ ______
-0.081774 0.54633 -0.81939 'ysrkqlzcms' true
所以,不要将C{5}.x
或S(5).x
编入索引,而是T.x(5)
。
答案 1 :(得分:0)
您可能需要cellfun
anonymous function(或for
循环)从每个单元格的内容中提取x
和y
字段:
plot(cellfun(@(t) t.x, ans(1:98,1)), cellfun(@(t) t.y, ans(1:98,1)))
注意:
()
使用索引而不是{}
,因为cellfun
需要一个单元格数组作为输入(有关索引单元格数组的更多信息here)。此外,如果要处理整个单元阵列,可以完全跳过索引,只需使用
plot(cellfun(@(t) t.x, ans), cellfun(@(t) t.y, ans))
两个匿名函数@(t) t.x
和@(t) t.y
作用于每个单元格的内容,即标量结构,并分别从x
或y
字段中提取。默认情况下,结果按cellfun
打包到标准(数字)数组中。
如果您的数据以更方便的方式组织会更容易,例如包含字段x
和y
的98×1结构数组,或者更好的是两个数字向量{{1 }和x
。