Fix table parse: combined column (#17039)

This commit is contained in:
Wang Qi
2026-07-17 16:58:54 +08:00
committed by GitHub
parent 344477f3f0
commit 6a1224ba04
2 changed files with 49 additions and 6 deletions

View File

@@ -39,6 +39,29 @@ from common import settings
logger = logging.getLogger(__name__)
def _deduplicate_column_names(columns):
reserved = {str(col) for col in columns}
used = set()
counts = Counter()
unique_columns = []
for col in columns:
name = str(col)
counts[name] += 1
if name not in used:
unique_columns.append(name)
used.add(name)
continue
suffix = counts[name]
new_name = f"{name}_{suffix}"
while new_name in used or new_name in reserved:
suffix += 1
new_name = f"{name}_{suffix}"
counts[name] = suffix
unique_columns.append(new_name)
used.add(new_name)
return unique_columns
class Excel(ExcelParser):
def __call__(self, fnm, binary=None, from_page=0, to_page=MAXIMUM_TASK_PAGE_NUMBER, callback=None, **kwargs):
if not binary:
@@ -95,6 +118,7 @@ class Excel(ExcelParser):
if len(data) == 0:
continue
df = pd.DataFrame(data, columns=headers)
df.columns = _deduplicate_column_names(df.columns)
for img in pending_cell_images:
excel_row = img["row_from"] - 1
excel_col = img["col_from"] - 1
@@ -402,7 +426,7 @@ def chunk(filename, binary=None, from_page=0, to_page=MAXIMUM_TASK_PAGE_NUMBER,
callback(0.3, ("Extract records: {}~{}".format(from_page, min(len(lines), to_page)) + (f"{len(fails)} failure, line: %s..." % (",".join(fails[:3])) if fails else "")))
dfs = [pd.DataFrame(np.array(rows), columns=headers)]
dfs = [pd.DataFrame(np.array(rows), columns=_deduplicate_column_names(headers))]
elif re.search(r"\.csv$", filename, re.IGNORECASE):
callback(0.1, "Start to parse.")
txt = get_text(filename, binary)
@@ -425,7 +449,7 @@ def chunk(filename, binary=None, from_page=0, to_page=MAXIMUM_TASK_PAGE_NUMBER,
callback(0.3, (f"Extract records: {from_page}~{from_page + len(rows)}" + (f"{len(fails)} failure, line: {','.join(fails[:3])}..." if fails else "")))
dfs = [pd.DataFrame(rows, columns=headers)]
dfs = [pd.DataFrame(rows, columns=_deduplicate_column_names(headers))]
else:
raise NotImplementedError("file type not supported yet(excel, text, csv supported)")
@@ -450,10 +474,8 @@ def chunk(filename, binary=None, from_page=0, to_page=MAXIMUM_TASK_PAGE_NUMBER,
del df[n]
clmns = df.columns.values
if len(clmns) != len(set(clmns)):
col_counts = Counter(clmns)
duplicates = [col for col, count in col_counts.items() if count > 1]
if duplicates:
raise ValueError(f"Duplicate column names detected: {duplicates}\nFrom: {clmns}")
df.columns = _deduplicate_column_names(clmns)
clmns = df.columns.values
txts = list(copy.deepcopy(clmns))
py_clmns = [PY.get_pinyins(re.sub(r"(/.*|[^]+?|\([^()]+?\))", "", str(n)), "_")[0] for n in clmns]

View File

@@ -40,6 +40,9 @@ TEST_CSV = b"""row_id,title,content,country,category
2,Oil prices surge,Brent crude jumped 4.2 percent,Global,Economy
3,AI regulation proposed,EU unveiled a draft regulation,EU,Technology
"""
TEST_DUPLICATE_COLUMNS_CSV = b"""name,name,name_2
Alice,Engineer,Team A
"""
FILENAME = "test.csv"
KB_ID = "test_kb_id"
@@ -107,6 +110,24 @@ def _run_chunk(table_module, parser_config: dict, mock_update_kb: MagicMock):
)
def test_chunk_deduplicates_repeated_column_names(table_module, mock_update_kb: MagicMock):
chunks = table_module.chunk(
FILENAME,
binary=TEST_DUPLICATE_COLUMNS_CSV,
callback=_noop_callback,
kb_id=KB_ID,
parser_config={},
lang="Chinese",
)
assert len(chunks) == 1
cww = chunks[0]["content_with_weight"]
assert "- name: Alice" in cww
assert "- name_3: Engineer" in cww
assert "- name_2: Team A" in cww
args, kwargs = mock_update_kb.call_args
assert args[1]["table_column_names"] == ["name", "name_3", "name_2"]
def test_chunk_auto_mode_all_columns_in_text_and_stored(table_module, mock_update_kb: MagicMock):
parser_config: dict = {}
chunks = _run_chunk(table_module, parser_config, mock_update_kb)