идентификаторы совпадений + найти число в матрице в Matlab - PullRequest
1 голос
/ 22 июля 2011

У меня проблема с сопоставлением элементов в 2 матрицах.Первый элемент может быть сопоставлен с использованием ismember, но второй элемент должен находиться в пределах диапазона.Пожалуйста, смотрите пример ниже:

% col1 is integerID, col2 is a number.       -->col1 is Countrycode, col2 is date
bigmat = [ 600 2  
           600 4  
           800 1  
           800 5  
           900 1] ;

% col1 is integerID, col2 is VALUE, col2 is a range    -->value is Exchange rate
datamat = {...
           50   0.1   [2 3 4 5 6]       % 2:6
           50   0.2   [9 10 11]         % 9:11
           600  0.01  [1 2 3 4]         % 1:4
           600  0.2   [8 9 10]          % 8:10
           800  0.12  [1]               % 1:1
           800  0.13  [3 4]             % 3:4
           900  0.15  [1 2]      } ;    % 1:2

I need the answer as:
    ansmat = [ 600 2  0.01
               600 4  0.01
               800 1  0.12
               800 5  nan               % even deleting this row is fine
               930 1  0.15 ] ;

Для простоты:

  1. Все intID из matrix_1 существуют в matrix_2.
  2. Числа в диапазоне - даты!В пределах диапазона эти числа являются последовательными: [1 2 ... 5]
  3. Для любого идентификатора даты в следующей строке не являются непрерывными.Например, вы можете увидеть [1 2 3 4], а затем [8 9 10] в следующем ряду.

bigmat - это огромная матрица!300 000-500 000 строк и поэтому векторизованный код будет принят.datamat примерно 5000 строк или меньше.Вы можете преобразовать ячейку в матрицу.Для каждого ряда у меня есть минимум и максимум.3 столбца минимальный: максимальный.Спасибо!

Ответы [ 2 ]

0 голосов
/ 22 июля 2011

Я не совсем уверен, что понимаю ... должна ли быть вторая запись '600 4 0,02'?

В любом случае, вы можете попробовать что-то вроде:

% grab first column
col = bigmat(:, 1);

% find all entries in column that are equal to ID
rel = (col == id);

% retrieve just those rows
rows = bigmat(rel, :);

Затем, когда у вас есть нужные вам строки из ваших матриц, вы можете объединить их вместе следующим образом:

result = [rowsA(1:3) rowsB(2) rowsC(5:6)];
0 голосов
/ 22 июля 2011

Вот одна из возможных реализаций:

%# data matrices
q = [
    600 2  
    600 4  
    800 1  
    800 5  
    900 1
];
M = {
    50   0.1   [2 3 4 5 6]
    50   0.2   [9 10 11]
    600  0.01  [1 2 3 4]
    600  0.2   [8 9 10]
    800  0.12  [1]
    800  0.13  [3 4]
    900  0.15  [1 2]
};

%# build matrix: ID,value,minDate,maxDate
M = [cell2num(M(:,1:2)) cellfun(@min,M(:,3)) cellfun(@max,M(:,3))];

%# preallocate result
R = zeros(size(M,1),3);

%# find matching rows
c = 1;             %# counter
for i=1:size(q,1)
    %# rows indices matching ID
    ind = find( ismember(M(:,1),q(i,:)) );

    %# out of those, keep only those where date number is in range
    ind = ind( M(ind,3) <= q(i,2) & q(i,2) <= M(ind,4) );

    %# check if any
    num = numel(ind);
    if num==0, continue, end

    %# extract matching rows
    R(c:c+num-1,:) = [M(ind,1) repmat(q(i,2),[num 1]) M(ind,2)];
    c = c + num;
end

%# remove excess
R(c:end,:) = [];

Результат, как и ожидалось:

>> R
R =
          600            2         0.01
          600            4         0.01
          800            1         0.12
          900            1         0.15
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...