来自阵列和单元阵列的传感器时间分布



我在matlab中有一个单元格数组和一个数字数组,它们是固有链接的。数字数组(A)包含来自多个数据源的一系列时间,例如每次测量的时间。阵列是n个传感器(列)乘以n个测量值(行)。由于0是有效时间,因此默认情况下数组填充为-1。

A = [ [ 100 110  -1  -1 ] ; ...
      [  -1 200 180  -1 ] ; ...
      [  -1 200 210 240 ] ; ...
      [ 400  -1  -1 450 ] ];

该单元格包含按时间顺序排列的数字数组每一行的传感器。每个单元元素都包含一个矢量,按照传感器进行测量的顺序显示传感器。

C = { [1 2] [3 2] [2 3 4] [1 4]};

我想看看相对于每个传感器的时间分布,例如,相对于传感器,传感器2/3/4(当它们存在时)的时间分布是什么?

例如。。。

传感器1参与第一次和第四次测量,其他探测器分别为+10(100->110)和+50(400->450)。在这种情况下,我希望返回一个数组,例如[1050]。

传感器2涉及前三个事件,其中一个是三方事件。在这种情况下,它sensor2并不总是第一个触发的,所以有些值会是负数。在这种情况下,我希望返回〔-10-20+10+40)〕

使用相同的逻辑传感器3应返回[20-10 30]和传感器4[-40-30-50]。

我相信应该有一个简单的方法来做这件事,但我无法理解。当然,我举的例子很简单。。。。通常我要处理几十个传感器和100000个测量值,所以在每一列/每一行上循环需要很长时间。。。并且如果在每次测量中只有两个(或大约两个)传感器触发,则通常得出很少的结果。出于这个原因,我希望使用单元格数组中的元素只访问数字数组中正确的元素。

有什么想法吗?

如果我已经很好地理解了这个问题,可以解决它,那么您似乎不需要为输出担心C。这是代码-

num_sensors = size(A,2)%// No. of sensors
A = A'; %//' The tracking goes row-wise, so transpose the input array
A(A==-1)=nan; %//set minus 1's to NaNs as excluding elements
out = cell(num_sensors,1);  %// storage for ouput
for k1 = 1:num_sensors
    %// Per sensor subtractions
    per_sensor_subt = bsxfun(@minus,A,A(k1,:)); 
    %// Set all elements of its own row to NaNs to exclude own subtractions
    per_sensor_subt(k1,:)=nan; 
    %// Get all the non-nans that correspond to the valid output
    out{k1} = per_sensor_subt(~isnan(per_sensor_subt));
end

输出-

>> celldisp(out)
out{1} =
    10
    50
out{2} =
   -10
   -20
    10
    40
out{3} =
    20
   -10
    30
out{4} =
   -40
   -30
   -50

当你已经确认每个单元格的输出顺序并不重要时,你可以使用一种简化的方法,它可能会更快——

num_sensors = size(A,2)%// No. of sensors
A(A==-1)=nan; %//set minus 1's to NaNs as excluding elements
out = cell(num_sensors,1);  %// storage for ouput
for k1 = 1:num_sensors
    %// Per sensor subtractions
    per_sensor_subt = bsxfun(@minus,A,A(:,k1)); 
    %// Set all elements of its own row to NaNs to exclude own subtractions
    per_sensor_subt(:,k1)=nan; 
    %// Get all the non-nans that correspond to the valid output
    out{k1} = per_sensor_subt(~isnan(per_sensor_subt));
end

如果内存允许,完全矢量化解决方案-

[m,n] = size(A)%// No. of sensors and measurements
A(A==-1)=nan; %//set minus 1's to NaNs as excluding elements
%// Per sensor subtractions
per_sensor_subt = bsxfun(@minus,A,permute(A,[1 3 2]))
%// Set all elements of its own row to NaNs to exclude own subtractions
own_idx = bsxfun(@plus,bsxfun(@plus,[1:m]',[0:n-1]*numel(A)),[0:n-1]*m);%//'
per_sensor_subt(own_idx)=nan;
%// Linear and row-col-dim3 indices of valid subtractions
idx = find(~isnan(per_sensor_subt))
[x,y,z] = ind2sub(size(per_sensor_subt),idx)
%// Get per sensor output
out = arrayfun(@(n) per_sensor_subt(idx(z==n)),1:n,'un',0)

如果你想计算C,请使用这种方法-

%// Sort A row-wise
[sortedA,sorted_idx] = sort(A,2)
%// Set all invalid indices to zeros, so that later on we can use `nonzeros`
%// to extract out the valid indices
valid_sorted_idx = sorted_idx.*(sortedA~=-1)
%// Convert to a cell array
valid_sorted_idx_cell = mat2cell(valid_sorted_idx,ones(1,size(A,1)),size(A,2))
%// Extract the valid ones(nonzero indices) for the final output, C
C = cellfun(@(x) nonzeros(x), valid_sorted_idx_cell,'un',0)

最新更新