Pandas DataFrame条件判断错误:分组列匹配结果异常求助
Pandas分组匹配逻辑错误排查
数据说明
df_doc
doc_id subgroup_doc 12345 A01B13/42 67891 B01C10/257 23456 C02D7/18
df_check
subgroup_doc main sg_1 sg_2 sg_3 sg_4 A01B13/42 13/00 13/04 13/42 NaN NaN B01C10/257 10/00 10/02 10/25 10/257 NaN C02D7/18 7/00 7/01 7/18 NaN NaN
预期结果
doc_id subgroup_doc doc_group 12345 A01B13/42 sg_2 67891 B01C10/257 sg_3 23456 C02D7/18 sg_2
编写的函数
def checkdot_ipc_sg2_v2(raw_data,check_group): new_raw_data = raw_data[['doc_id','subgroup_doc']] merge_find_group = pd.merge(new_raw_data, check_group, how='left', on=['subgroup_doc']) t_doc = merge_find_group.subgroup_doc.str.split('/') s_doc_sg2 = merge_find_group.sg_2.str.split('/') s_doc_sg1 = merge_find_group.sg_1.str.split('/') s_doc_sg0 = merge_find_group.maingroup.str.split('/') raw_data['doc_checkgp'] = t_doc.str[0]+ "/" + s_doc_sg2.str[1].str[:] raw_data['doc_group'] = 'sg_2' if(raw_data['doc_checkgp'].isna().any()): raw_data['doc_checkgp'].fillna(t_doc.str[0]+ "/" + s_doc_sg1.str[1].str[:], inplace=True) raw_data['doc_group'] = 'sg_1' if(raw_data['doc_checkgp'].isna().any()): raw_data['doc_checkgp'].fillna(t_doc.str[0]+ "/" + s_doc_sg0.str[1].str[:], inplace=True) raw_data['doc_group'] = 'sg_0'
实际输出
doc_id subgroup_doc doc_checkgp doc_group 12345 A01B13/42 A01B13/42 sg_0 67891 B01C10/257 B01C10/257 sg_0 23456 C02D7/18 C02D7/18 sg_0
问题分析
- 列名错误:
check_group中的列名为main,但代码里误用了maingroup,导致s_doc_sg0全为NaN,直接触发最内层if判断。 - 全局条件判断错误:
isna().any()是判断整个列是否存在任意NaN值,一旦满足就会将整个doc_group列覆盖为'sg_1'或'sg_0',而非逐行判断每个文档的匹配级别。 - 匹配逻辑偏差:当前逻辑直接拼接sg_2的部分,没有判断
subgroup_doc的后缀是否与对应级别的后缀匹配,且未从最高级别(sg_4)到最低级别(main)依次检查优先级。
修复方案
修正列名错误,改用逐行优先级匹配逻辑,示例代码如下:
import numpy as np import pandas as pd def checkdot_ipc_sg2_v2(raw_data, check_group): # 合并数据,修正列名错误 merge_df = pd.merge(raw_data[['doc_id', 'subgroup_doc']], check_group, how='left', on='subgroup_doc') # 提取subgroup的后缀部分(如A01B13/42的42) merge_df['suffix'] = merge_df['subgroup_doc'].str.split('/').str[1] # 定义从高到低的匹配规则:先检查sg_4,再sg_3,以此类推 conditions = [ merge_df['sg_4'].str.split('/').str[1] == merge_df['suffix'], merge_df['sg_3'].str.split('/').str[1] == merge_df['suffix'], merge_df['sg_2'].str.split('/').str[1] == merge_df['suffix'], merge_df['sg_1'].str.split('/').str[1] == merge_df['suffix'], merge_df['main'].str.split('/').str[1] == merge_df['suffix'] ] # 对应每个条件的分组名称 choices = ['sg_4', 'sg_3', 'sg_2', 'sg_1', 'sg_0'] # 逐行匹配,赋值对应的分组 merge_df['doc_group'] = np.select(conditions, choices, default='unknown') # 合并回原数据,返回结果 result = raw_data.merge(merge_df[['doc_id', 'doc_group']], on='doc_id', how='left') return result
执行效果
调用该函数后,将得到符合预期的结果:
doc_id subgroup_doc doc_group 12345 A01B13/42 sg_2 67891 B01C10/257 sg_3 23456 C02D7/18 sg_2
内容的提问来源于stack exchange,提问作者Hook Im
相关产品推荐
相关产品推荐

