You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中区分混合单元格中的产品编码与数量

如何在Python中区分混合单元格中的产品编码与数量

看起来你遇到的核心问题是列位置的语义偶尔失效,再加上5位数量和产品编码的数字重叠,导致了误判。结合你的Excel结构(左右分栏的表格、物种标题分区),我们可以从几个维度优化逻辑,让识别更精准:

1. 优先利用列的语义定位,避免“一刀切”判断

你当前的代码里,不管是产品编码列还是数量列,只要是5位数字就判定为产品编码,这很容易把数量列里的5位数字误认。其实表格的列本身就有明确的语义:产品编码列(左表的第3列、右表的第8列)本来就该放编码,数量列(左表第4列、右表第9列)本来就该放数量,我们应该优先尊重这个位置逻辑:

修改判断函数与列处理逻辑

def is_product_code(value):
    # 只针对产品编码列的判断:必须是整数(或可转整数的浮点数),且为5位
    if pd.isna(value):
        return False
    # 处理12345.0这类浮点数情况
    try:
        int_val = int(value)
    except (ValueError, TypeError):
        return False
    return len(str(int_val)) == 5

# 处理左表时的逻辑调整
if current_species_left and left_col:
    # 产品编码列:只判断当前列是否符合编码规则
    product_code = row[2] if not pd.isna(row[2]) and is_product_code(row[2]) else None
    # 数量列:直接取值,不再用编码规则排除(哪怕是5位数字,也优先按数量处理)
    quantity = row[3] if not pd.isna(row[3]) else None
    value = row[4] if not pd.isna(row[4]) else None

    # 后续添加到data_rows的逻辑不变...

这样就不会把数量列里的5位数字误判成产品编码了——毕竟数量列的本职就是记录数量,哪怕数值刚好是5位,也优先按数量处理。

2. 处理“同一单元格混合编码与数量”的场景

如果某些单元格里同时存在编码和数量(比如内容是12345 100或12345,50.5),我们可以用正则表达式来拆分内容:匹配5位数字作为编码,剩下的部分提取为数量。

新增拆分辅助函数

import re

def split_mixed_cell(cell_value):
    if pd.isna(cell_value):
        return (None, None)
    cell_str = str(cell_value).strip()
    # 匹配独立的5位数字(避免和更长数字混淆)
    code_match = re.search(r'\b\d{5}\b', cell_str)
    product_code = int(code_match.group()) if code_match else None
    
    # 提取数量:移除编码后,匹配整数或小数
    quantity_str = re.sub(r'\b\d{5}\b', '', cell_str).strip().replace(',', '')
    try:
        quantity = float(quantity_str) if '.' in quantity_str else int(quantity_str)
    except ValueError:
        quantity = None
    return (product_code, quantity)

在列处理中加入混合内容判断

比如处理左表行时:

if current_species_left and left_col:
    cell_code = row[2]
    cell_qty = row[3]
    prod_code = None
    qty = None

    # 先处理产品编码列的混合情况
    if not pd.isna(cell_code):
        if len(str(cell_code).strip().split()) >= 2:
            # 单元格混合了编码和数量,拆分
            code_from_code_col, qty_from_code_col = split_mixed_cell(cell_code)
            prod_code = code_from_code_col
            # 如果数量列是空的,用拆分出的数量
            if pd.isna(cell_qty):
                qty = qty_from_code_col
        else:
            # 正常情况,按编码规则判断
            prod_code = cell_code if is_product_code(cell_code) else None

    # 再处理数量列的混合情况
    if not pd.isna(cell_qty):
        if len(str(cell_qty).strip().split()) >= 2:
            # 数量列混合了编码和数量,拆分
            code_from_qty_col, qty_from_qty_col = split_mixed_cell(cell_qty)
            qty = qty_from_qty_col
            # 如果编码列是空的,用拆分出的编码
            if prod_code is None:
                prod_code = code_from_qty_col
        else:
            qty = cell_qty

    value = row[4] if not pd.isna(row[4]) else None
    # 正常添加到data_rows...

3. 补充业务规则(如果有)

如果你们的产品编码有固定范围(比如都是10000-50000之间的数字),可以把这个规则加入判断函数,进一步过滤误判:

def is_product_code(value):
    if pd.isna(value):
        return False
    try:
        int_val = int(value)
    except (ValueError, TypeError):
        return False
    # 新增:产品编码必须在指定范围内
    return len(str(int_val)) == 5 and 10000 <= int_val <= 50000

4. 容错标记:人工核查存疑行

如果还是有无法确定的情况,可以在结果中新增Flag字段标记存疑,方便后续人工核对:

# 在添加到data_rows时加入标记
flag = "正常"
if prod_code is not None and qty is not None:
    try:
        if len(str(int(qty))) == 5:
            flag = "存疑:编码与数量均为5位"
    except (ValueError, TypeError):
        pass

data_rows.append({
    "Species": current_species_left,
    "Product Code": prod_code,
    "Product": left_col,
    "Quantity": qty,
    "Value": value,
    "Company Name": company_info["Company Name"],
    "Mailing Address": company_info["Mailing Address"],
    "Plant Name": company_info["Plant Name"],
    "Plant Address": company_info["Plant Address"],
    "Source Sheet": sheet,
    "Flag": flag  # 新增标记字段
})

按照这些思路修改你的代码,应该能大幅提升识别的准确性啦!

备注:内容来源于stack exchange,提问作者JonathonV92

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 19:29:49