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

使用janitor包conditional_join多条件匹配时遇TypeError问题求助

问题描述

需要基于以下三个条件,从查找表中为数据集匹配对应的Factor值:

  • 数据集的State与查找表的State_Cd完全匹配
  • 数据集的Deductible与查找表的Deductible完全匹配
  • 数据集的Revenue落在查找表的Revenue_1和Revenue_2区间内(满足Revenue_1 <= Revenue <= Revenue_2)

数据定义

查找表(Lookup_Table)

import pandas as pd

Lookup_Table = {'State_Cd': ['TX','TX','TX','TX','CA','CA','CA','CA'],
        'Deductible': [0,0,1000,1000,0,0,1000,1000],
                'Revenue_1': [-99999999,25000000,-99999999,25000000,-99999999,25000000,-99999999,25000000],
                'Revenue_2': [24999999,99000000,24999999,99000000,24999999,99000000,24999999,99000000],
                'Factor': [0.15,0.25,0.2,0.3,0.11,0.15,0.13,0.45]
        }   
Lookup_Table = pd.DataFrame(Lookup_Table, columns = ['State_Cd','Deductible','Revenue_1','Revenue_2','Factor'])

数据集(Dataset)

Dataset = {'Policy': ['A','B','C'],
        'State': ['CA','TX','TX'],
                'Deductible': [0,1000,0],
                'Revenue': [10000000,30000000,1000000]          
}   
Dataset = pd.DataFrame(Dataset, columns = ['Policy','State','Deductible','Revenue'])

预期输出

Policy State  Deductible    Revenue  Factor
0      A    CA           0   10000000    0.11
1      B    TX        1000   30000000    0.30
2      C    TX           0    1000000    0.15

报错情况

尝试使用janitor的conditional_join实现匹配时,出现如下错误:

尝试代码

import janitor

Data_Final = (Dataset.conditional_join(Lookup_Table,
          ('Revenue', 'Revenue_1', '>='), 
          ('Revenue', 'Revenue_2', '<='),
          ('State', 'State_Cd', '=='),
          ('Deductible', 'Deductible', '=='),
          how = 'left',sort_by_appearance = False
             )) 

错误信息

TypeError: __init__() got an unexpected keyword argument 'copy'

问题原因与解决方案

该错误的核心原因是janitor版本与pandas版本不兼容:conditional_join内部调用的pandas API在新版本中移除了copy参数,但旧版janitor仍在传递该参数,导致报错。以下是三种可行的解决方法:

方案1:调整janitor版本

安装与当前pandas版本兼容的janitor版本,例如0.24.0版本(经测试适配多数较新pandas版本):

pip install pyjanitor==0.24.0

安装完成后重新运行原代码即可正常执行。

方案2:使用pandas原生方法实现

无需依赖janitor,通过merge+条件过滤的方式实现需求:

# 先按匹配字段合并两个表
merged = Dataset.merge(
    Lookup_Table,
    left_on=['State', 'Deductible'],
    right_on=['State_Cd', 'Deductible'],
    how='left'
)
# 过滤满足Revenue区间条件的行
result = merged[(merged['Revenue'] >= merged['Revenue_1']) & (merged['Revenue'] <= merged['Revenue_2'])]
# 保留需要的列并重置索引
result = result[['Policy', 'State', 'Deductible', 'Revenue', 'Factor']].reset_index(drop=True)
print(result)

也可以用query方法简化过滤逻辑:

merged = Dataset.merge(
    Lookup_Table,
    left_on=['State', 'Deductible'],
    right_on=['State_Cd', 'Deductible'],
    how='left'
)
result = merged.query('Revenue >= Revenue_1 and Revenue <= Revenue_2')[['Policy', 'State', 'Deductible', 'Revenue', 'Factor']].reset_index(drop=True)

方案3:用numpy广播实现匹配

针对小规模数据集,可通过numpy广播构建匹配矩阵,直接提取对应Factor:

import numpy as np

# 构建匹配条件的布尔矩阵
match_mask = (
    (Dataset['State'].values[:, None] == Lookup_Table['State_Cd'].values) &
    (Dataset['Deductible'].values[:, None] == Lookup_Table['Deductible'].values) &
    (Dataset['Revenue'].values[:, None] >= Lookup_Table['Revenue_1'].values) &
    (Dataset['Revenue'].values[:, None] <= Lookup_Table['Revenue_2'].values)
)

# 提取匹配到的Factor值
Dataset['Factor'] = Lookup_Table['Factor'].values[np.argmax(match_mask, axis=1)]
print(Dataset)

内容的提问来源于stack exchange,提问作者Bustergun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:55:18