数据变量是3x9阵列,其中第一行是电压,第二行是计数,第三行是错误。我想平均每个电压的计数/误差,以便处理后的数组类似于
combined = [1,2,3;.99,.1.2,1.3;.2,.3,.5]
到目前为止,我的尝试是:
data = [1,1,1,2,2,2,3,3,3;...
.98,.99,.98,1.1,1.2,1.2,1.3,1.3,1.4;...
.3,.2,.2,.3,.3,.4,.5,.4,.5];
volt = data(1,:);
v_uniq=unique(volt);%Array of unique voltage values
for k=1:length(v_uniq)
volt_i=find(volt==v_uniq(k));%Indices for set of repeating values
combined_m(k)=mean(data(2,volt_i(1):volt_i(end)).')';%averaged means
combined_e(k)=mean(data(3,volt_i(1):volt_i(end)).')';%averaged error
combined(k) = [combined_m(k);combined_e(k)];
%combined(k)=combined(k);
end
挑战性的部分是在每次迭代后附加组合数组,因为v_uniq本身就是一个数组,并且在尝试迭代时会导致问题。
有没有办法在不必索引v_uniq的情况下附加组合数组?或者,如果没有,还有另一种更简单的方法来解决这个问题吗?
答案 0 :(得分:4)
如果您想让您的代码正常工作,请在上面对您的评论中使用Daniel的建议。只需将for
循环代码的最后一行替换为:
combined(:,k) = [combined_m(k);combined_e(k)];
您想插入一列,显示每个唯一电压的组合计数和错误。
但是,我建议使用accumarray
而不是for
循环方法,并使用电压作为键,并使用矩阵的其他两行作为值。 accumarray
的工作原理是您有两个数组:keys
和values
。对于keys
中存储的每个值,我们会在values
中看到相应的数字,并将此数字放入由keys
索引的bin中。一旦我们完成所有这些分箱,您就可以使用一个功能,将每个bin的所有这些条目组合在一起。默认情况下,accumarray
使用sum
,因此您只需将所有映射到每个bin的值相加。
但是,对于您的情况,您将使用mean
作为应用于每个箱的函数,以查找每个唯一电压的平均误差和计数。像这样:
data = [1,1,1,2,2,2,3,3,3;...
.98,.99,.98,1.1,1.2,1.2,1.3,1.3,1.4;...
.3,.2,.2,.3,.3,.4,.5,.4,.5];
ave_counts = accumarray(data(1,:).', data(2,:).', [], @mean);
ave_error = accumarray(data(1,:).', data(3,:).', [], @mean);
combined = [ave_counts ave_error];
在accumarray
中,第一个参数是键,在我们的例子中是电压,values
是计数或错误 - 基本上是那些需要组合的值。
ave_counts
将包含每个唯一电压的平均计数,而ave_error
将包含每个唯一电压的平均误差。然后我们可以将这些组合成一个2列矩阵,就像最后一行代码一样,创建combined
,就像在代码中看到的那样。
由于您的电压已经逐渐增加,这意味着每个元素都与该电压完全对应。运行此功能后,我就可以获得ave_counts
和ave_error
:
>> ave_counts
ave_counts =
0.9833
1.1667
1.3333
>> ave_error
ave_error =
0.2333
0.3333
0.4667
这表示对于voltage = 1
,平均值和平均误差分别为0.9833
和0.2333
。您可以通过手动计算来验证这一点。前三个计数和错误是voltage = 1
,如果我们计算平均误差和计数,我们得到:
(0.98+0.99+0.98) / 3 = 0.9833 <-- Average count for voltage = 1
(0.3+0.2+0.3) / 3 = 0.2333 <-- Average error for voltage = 1
同样适用于voltage = 2
:
(1.1+1.2+1.2) / 3 = 1.1667 <-- Average count for voltage = 2
(0.3+0.3+0.4) / 3 = 0.3333 <-- Average error for voltage = 2
最后为voltage = 3
:
(1.3+1.3+1.4) / 3 = 1.3333 <-- Average count for voltage = 3
(0.5+0.4+0.5) / 3 = 0.4667 <-- Average error for voltage = 3
我们手动计算的数量恰好是accumarray
两个数量的输出。
accumarray
仅用于接受整数键。如果您有浮点值,您仍然可以使用accumarray
,但您必须先进行一些预处理。我要做的是使用unique
并专门使用第三个输出。第三个输出获取输入中的每个唯一值,并为其分配整数ID。任何相同的值都会被赋予相同的整数ID ,因此非常适合作为accumarray
的输入。您还需要第一个输出来跟踪combined
矩阵每行的平均电压。
因此,您将使用unique
的第三个输出作为accumarray
的输入。因此,做这样的事情:
[voltages,~,id] = unique(data(1,:));
ave_counts = accumarray(id, data(2,:).', [], @mean);
ave_error = accumarray(id, data(3,:).', [], @mean);
combined = [ave_counts ave_error];
在这种情况下,ave_counts
和ave_error
的每个元素都对应于voltages
中存储的相同元素。因此,voltages(1)
将对应于combined
的第一行,voltages(2)
将对应于combined
的第二行,依此类推。
为了完整性,如果我们使用您的示例数据运行上述内容,这就是我们为voltages
和combined
获取的内容:
>> voltages
voltages =
1 2 3
>> combined
combined =
0.9833 0.2333
1.1667 0.3333
1.3333 0.4667
因此,voltage = 1
给我们的平均点数为0.9833
,平均误差为0.2333
,依此类推。