如何对两个Timetable执行不按键排序的Outerjoin并优先高优数据
实现两个Timetable的非排序外连接并优先保留高质量数据
问题背景
需要对两个包含相同变量的Timetable执行外连接,要求合并后不按键值排序,且相同时间样本下优先保留table1(高质量数据)的行,再保留table2(低质量数据)的行,最终通过retime提取每个时间点的优先值。
方法一:保留所有原始行并调整顺序
如果需要保留所有原始行(包括重复时间的条目),可以通过标记来源+分组排序的方式实现:
% 定义原始数据 table1 = array2timetable([2;5], 'RowTimes', datetime(2000:2001,1,1), 'VariableNames', {'A'}); table2 = array2timetable([1;3], 'RowTimes', datetime(2001:2002,1,1), 'VariableNames', {'A'}); % 为两个表添加来源标记(1代表table1,2代表table2) table1_marked = addvars(table1, ones(height(table1),1), 'NewVariableNames', 'Source'); table2_marked = addvars(table2, 2*ones(height(table2),1), 'NewVariableNames', 'Source'); % 垂直合并两个表 combined = [table1_marked; table2_marked]; % 按时间分组,每组内按来源标记排序(table1的行优先) sorted_combined = splitapply(... @(t,a,s) sortrows([t,a,s], 3), ... combined.Time, combined.A, combined.Source); % 转换回Timetable并移除来源标记 sorted_combined = array2timetable(... sorted_combined(:,2), ... 'RowTimes', sorted_combined(:,1), ... 'VariableNames', {'A'});
执行后得到的sorted_combined完全符合期望顺序:
Time A ___________ _ 01-Jan-2000 2 01-Jan-2001 5 01-Jan-2001 1 01-Jan-2002 3
再通过retime提取优先值:
final_table = retime(sorted_combined, unique(sorted_combined.Time), 'firstvalues');
方法二:直接生成去重后的结果(更高效)
如果不需要保留重复时间的原始行,仅需最终的优先结果,可以跳过合并排序步骤,直接通过时间匹配+值填充实现,效率更高:
% 定义原始数据 table1 = array2timetable([2;5], 'RowTimes', datetime(2000:2001,1,1), 'VariableNames', {'A'}); table2 = array2timetable([1;3], 'RowTimes', datetime(2001:2002,1,1), 'VariableNames', {'A'}); % 获取所有唯一时间点,保持table1时间在前的稳定顺序 all_times = union(table1.Time, table2.Time, 'stable'); % 初始化结果数组 A_values = nan(size(all_times)); % 先填充table1中的数据 idx_table1 = ismember(all_times, table1.Time); A_values(idx_table1) = table1.A(ismember(table1.Time, all_times(idx_table1))); % 填充table2中table1未覆盖的数据 idx_table2 = ~idx_table1 & ismember(all_times, table2.Time); A_values(idx_table2) = table2.A(ismember(table2.Time, all_times(idx_table2))); % 生成最终Timetable final_table = timetable(all_times, A_values, 'VariableNames', {'A'});
直接得到最终结果:
Time A ___________ _ 01-Jan-2000 2 01-Jan-2001 5 01-Jan-2002 3
方法对比
- 方法一:保留所有原始行,适合需要查看完整原始数据的场景,但数据量大时性能略低。
- 方法二:直接生成去重结果,避免了中间排序步骤,性能更优,适合仅需最终优先值的场景。
内容的提问来源于stack exchange,提问作者WJB
相关产品推荐
相关产品推荐

