Orange Python中按elv角度分区间生成子表后如何按axis=1横向拼接表格
Orange3 仰角区间拆分后横向拼接实现方案
补充说明:Orange3内置的
Table.concatenate方法仅支持同Domain结构的表做纵向行拼接,没有提供不同列结构的横向拼接接口,这就是你感觉拼接操作被限制的根本原因——不是功能做了硬性限制,是设计上没有覆盖该场景的内置方法,通过统一构造数据的路径完全可以实现目标效果。
核心实现思路
摒弃“先生成每个区间的独立子表、再尝试横向拼接”的路径,改为先完成所有区间的样本筛选,再统一构造全量列的Domain、一次性生成结果表,完全绕开跨Domain拼接的校验限制。最终生成的表会严格匹配你需要的列数(num个区间×2列/区间=2*num列,比如你举例的8个区间就是16列),总行数由所有区间里样本数最多的那个区间决定,样本数不足的区间列用Orange标准缺失值numpy.nan填充。
可直接复用的修正代码
from Orange.data.table import Table from Orange.data import Domain, ContinuousVariable import numpy as np # 与你原逻辑保持一致的参数配置 num = 10 # 期望拆分的区间总数 total_elv_coverage = 90.0 # 仰角总覆盖范围 interval = total_elv_coverage / num # 初始化存储结构:存所有列变量、存每个区间筛选出的样本数据 all_columns = [] interval_samples = [] for i in range(num): # 按原逻辑计算区间边界(左闭右开) low = i * interval high = (i + 1) * interval # 定义当前区间对应的两个特征列 elv_var = ContinuousVariable.make(f"elv{i}") err_var = ContinuousVariable.make(f"err{i}") all_columns.extend([err_var, elv_var]) # 筛选当前区间的样本,与原逻辑的筛选规则完全一致 current_interval_rows = [ row for row in in_data if row[0] >= low and row[0] < high ] interval_samples.append(np.array(current_interval_rows)) # 计算所有区间中的最大样本数,作为最终表的总行数 max_row_num = max([len(sample_arr) for sample_arr in interval_samples]) # 初始化全量数据矩阵,默认用numpy.nan填充缺失位置 full_data = np.full((max_row_num, 2 * num), np.nan) # 把每个区间的样本数据填充到矩阵对应列的位置 for col_pair_idx, sample_arr in enumerate(interval_samples): current_row_count = len(sample_arr) # 每个区间占两列:偶数列存err值,奇数列存elv值 full_data[:current_row_count, col_pair_idx * 2] = sample_arr[:, 1] full_data[:current_row_count, col_pair_idx * 2 + 1] = sample_arr[:, 0] # 一次性生成符合Orange规范的最终横向拼接表 final_domain = Domain(all_columns) final_merged_table = Table.from_numpy(final_domain, full_data)
操作注意事项
- 不要通过pandas拼接后再转换为Table的方式实现,这种做法容易丢失Orange Table内置的元数据属性,导致后续拖入Orange画布使用时出现兼容异常。
- 列的顺序可以通过调整变量定义时的追加顺序自由控制,比如需要把elv放在err前面,只要把变量追加逻辑改成
all_columns.extend([elv_var, err_var]),对应调整矩阵赋值的列位置即可。 - 代码里的区间边界逻辑和你原实现完全一致:满足
low <= elv < high的样本会被划入对应区间,不会因为逻辑调整改变原有的样本归属规则。
内容的提问来源于stack exchange,提问作者first thing's first.
相关产品推荐
相关产品推荐

