设置
我有一组捕获的数据。数据可以只在一个设备上捕获,也可以在多达十几个设备上捕获,每个设备都是阵列中的一列。我有一个先前的语句,我在数组上执行该语句,然后将其转换为逻辑数组,以便在数据中找到特定的兴趣点。由于数据的性质,有很多0,只有几个1。我需要返回一个带有1的索引的数组,这样我就可以返回并捕获*这些点之间的数据(参见下面的更新)。find
显然是函数的选择--然而,我需要的结果是,每个设备需要有1列。通常,find
将执行线性索引,而与数组的维度无关。
这些设备遵循一个模式--但并不完全相同。因此,使情况更复杂的是,根据数据捕获停止的确切时间,每列中的1的数量接近,但不能保证完全相同(它们通常彼此相差1个元素,但可能相差更多)。
MatLab代码尝试
由于这种差异,我不能使用以下简单的代码:
for p = 1:np
indices( :, p ) = find( device.data.cross( :, p ) );
end
备注:
np
是数据中的列数=捕获的设备数。devices
是代表设备集合的class
data
是包含在所有设备上捕获的数据的TimeTable
cross
是包含逻辑阵列的data
TimeTable
中的一列- 即使是这个简单的代码效率也很低,并生成代码分析器警告:
变量‘index’似乎在每次循环迭代时改变大小(在脚本中)。考虑为速度进行预分配。
正如预期的那样,它无法工作,因为我收到了类似以下内容的错误:
无法执行赋值,因为左侧的大小为448 x 1,右侧的大小为449 x 1。
我知道为什么会出现这个错误--在MATLAB中,数组中的每一列都必须有相同的行数,所以如果行大小不匹配,我就不能进行赋值。我需要以某种方式填充“短”栏。在这种情况下,重复最后一个索引将对我以后的操作起作用,而不会导致错误。
我想不出一个“好”的办法来做这件事。我不能预填充数组行,因为在完成查找操作之前,我不知道将有多少行。
我可以按如下方式更改代码:
indices = [];
for p = 1:np
tempindices = find( devices.data.cross(:, p) );
sizediff = size( tempindices, 1 ) - size( indices, 1 );
if p > 1
if sizediff > 0
padding = repmat(indices(end, 1:(p - 1)), sizediff, 1);
indices = [indices; padding];
elseif sizediff < 0
padding = repmat(tempindices(end), abs(sizediff), 1);
tempindices = [tempindices; padding];
end
end
indices(:,p) = tempindices;
end
注意:padarray
在这里会很有用,但我没有Image Processing Toolbox
,所以我不能使用它。
这段代码可以工作,但效率非常低,它在工作区中创建了多个原本不需要的变量,并在代码分析器中生成了多个“似乎在每次循环迭代中更改大小”的警告。有没有更有效的方法来做到这一点?
更新/补充信息:
我的问题需要一些更多的背景。鉴于devices.data.cross是一个逻辑数组,为了从表中的其他列“挑选”我想要的数据(正如我最初描述的问题),我可以从devices.data.cross中选择一列,并将该逻辑列作为下标传递以获得该数据。我在管用的地方就会这么做。然而,对于某些列,我需要选择索引之间的“块”数据,这就是我需要索引的地方。或者,至少我不知道另一种方法。
下面是我如何使用索引的示例代码:
for p = 1:np
for i = 2:num_indices
these_indices = indices(i-1, p):( indices(i, p) - 1 );
rmsvoltage = sqrt( mean( devices.data.voltage(these_indices).^2 ) );
end
end
这只是我对“大块”数据所做的一个例程。我还有几个传递这些数据块以进行处理的函数。
1条答案
按热度按时间wz8daaqr1#
当我正确理解您的问题时,下面的代码应该可以工作。我正在使用克里斯·卢恩戈在你问题下的评论中建议的方法。
关键元素是
[rowIdcs, colIdcs] = find( cros );
,它给出了cros
中值为1的位置的下标。请在内联中找到更多评论。