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

时间:2014-09-30 19:33:09

标签: matlab cell-array

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

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)。在这种情况下,我希望返回一个数组,如[10 50]。

传感器2涉及前三个事件,其中一个是三方事件。在这种情况下,sensor2并不总是第一个触发,因此某些值将为负值。在这种情况下,我希望返回[-10 -20 +10 +40)]

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

我确信应该有一个简单的方法来做到这一点,但我无法理解它。当然我给出的例子是一个非常简单的例子....通常我正在处理数十个传感器和100,000个测量值,因此在每个列/行上循环将花费很长时间......而且经常如果每次测量中只有两个(左右)传感器触发,则绘制的结果很少。出于这个原因,我希望使用单元格数组中的元素只访问数值数组中的正确元素。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

如果我已经很好地理解了问题,那么您似乎无需为输出担心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)