2014-12-03 3 views
1

У меня есть более 8+ таблиц в Matlab разной длины. Все они включают даты в их первом столбце. Я хотел бы получить пересечение всех этих таблиц в столбцах даты. Следующий небольшой пример с 3 таблицы показывает, что я хочу:Пересечение нескольких таблиц разной длины в Matlab

Date1=datenum(2011,6,7,0:24:240,0,0).'; 
Date2=datenum(2011,6,8,0:24:240,0,0).'; 
Date3=datenum(2011,6,5,0:24:240,0,0).'; 


T1 = table(Date1,ones(11,1),'VariableNames',{'Date','Var1'}) 
T2 = table(Date2,ones(11,1)*2,'VariableNames',{'Date','Var2'}) 
T3 = table(Date3,ones(11,1)*3,'VariableNames',{'Date','Var3'}) 

Таким образом, я хотел бы следующий вывод:

Date  Var1 Var2 Var3 
______ ____ ____ ____ 

734662 1  2  3 
734663 1  2  3 
734664 1  2  3 
734665 1  2  3 
734666 1  2  3 
734667 1  2  3 
734668 1  2  3 
734669 1  2  3 

Есть функция в Matlab, что может это сделать?

ответ

2

Функция intersect может быть полезной для вашего случая.

Я не уверен, как вы используете таблицы, но приведенный ниже код позволит вам найти индексы пересечения для каждого вектора DateN. После того, как у вас есть индексы, вы можете перестроить глобальную таблицу, которая включает только общие индексы между всеми таблицами.

[C,ia,ib ] = intersect(Date1,Date2) ; %// get indices of intersection of first 2 vectors (Date1&2) 
[D,ja,ix3] = intersect( C ,Date3) ; %// get indices of intersection of last result (Date1&2) with last vector (Date 3) 

ix1 = ia(ja) ; %// take only the common indices of the 2 intersection operations (For Date1) 
ix2 = ib(ja) ; %// take only the common indices of the 2 intersection operations (For Date2) 

%// Build the "common" table 
intersectionTable = [ Date1(ix1) Var1(ix1) Var2(ix2) Var3(ix3) ] ; 
+0

Спасибо. Однако, имея 8+ таблиц, это решение немного громоздко. Любые предложения по внедрению funtion для выполнения всего перекрестка сразу? – Mace

+0

ха-ха, конечно, для 8-го стола это будет довольно много строк кода, чтобы повторить. Для ваших 8 таблиц (или любых чисел на самом деле), если вы понимаете, что делает код, вы можете внедрить это в цикл, который затем может пересекать столько таблиц, сколько вам нужно. – Hoki

+0

да, спасибо! – Mace

2

Я написал очень тесно связан код для другого вопроса, и я подавляя полированный код функции здесь находит элементы пересекающихся и соответствующие индексы для нескольких массивов одновременно, не прибегая к какому-либо зацикливанию для вычислительной части. Вот код -

function [out_val,out_idx] = intersect_arrays(varargin) 

%// Concatenate all vector arrays into a 2D array 
if isrow(varargin{1}) 
    M = vertcat(varargin{:}); 
else 
    M = horzcat(varargin{:}).'; %//' 
end 

%// Find unique values for all elements in all arrays 
unqvals = unique(M(:),'stable')'; %//' 

%// Find unqiue elements common across all arrays (intersecting elements) 
out_val = unqvals(all(any(bsxfun(@eq,M,permute(unqvals,[1 3 2])),2),1)); 

%// Find first indices across all arrays holding the intersecting elements 
[~,idx] = max(bsxfun(@eq,M,permute(out_val,[1 3 2])),[],2); 
out_idx = squeeze(idx).'; %//' 

return 

Теперь, чтобы решить дело, мы можем использовать код функции, как так -

num_arrays = 3; %// Number of arrays to be used 

%// Find intersecting elements and their corresppinding indices in each array 
[int_ele,int_idx] = intersect_arrays(T1.Date,T2.Date,T3.Date) %// Add inputs here 

%// Create an array of all Var data 
all_idx = cat(2,T1.Var1,T2.Var2,T3.Var3)      %// Add inputs here 

%// Select Var data based on the intersecting indices 
select_idx = all_idx(bsxfun(@plus,int_idx,[0:num_arrays-1]*size(T1.Var1,1))) 

%// Output results as a numeric array and table 
out_array = [int_ele(:) select_idx] 
out_table = cell2table(num2cell(out_array),'VariableNames',... 
             {'Date','Var1','Var2','Var3'}) 

Выход -

out_table = 
    Date  Var1 Var2 Var3 
    ______ ____ ____ ____ 
    734662 1  2  3 
    734663 1  2  3 
    734664 1  2  3 
    734665 1  2  3 
    734666 1  2  3 
    734667 1  2  3 
    734668 1  2  3 
    734669 1  2  3