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

值与dtype均一致的DataFrame为何equals返回不等,测试失败?

问题原因分析

1. Test 1 失败原因

表面上两个DataFrame的值和dtype看似一致,但df.equals()返回False的核心原因是元素类型的隐性差异:

  • 函数中对Combo (NPI & Date)列执行了apply(lambda x : x if '<NA>' not in x else np.nan),即使测试数据中没有<NA>值,该列的元素类型会被识别为Union[str, float](因为np.nan是float类型)。
  • 测试用例的output中,Combo (NPI & Date)列的元素是纯字符串类型,pandas的equals()方法会严格检查每个元素的类型,因此返回False。

另外,days_since_dec_30_1899函数通过字符串分割处理Timestamp的方式不可靠,若Timestamp包含时区或特殊格式会直接报错。

2. Test 2 失败原因

当输入NPI为float64类型时:

  • 函数中将其转为Int64(可空整数类型),再转为字符串,此时NPI列的dtype是Nullable String(string类型)。
  • 测试用例的output中NPI列是普通的object dtype,equals()默认会检查dtype完全一致,因此返回False。

修复方案

方案1:优化日期计算函数(避免字符串分割)

替换不可靠的字符串处理逻辑,直接用Timestamp内置方法获取日期:

def days_since_dec_30_1899(input_date: pd.Timestamp) -> str:
    delta = input_date.date() - dtm_date(1899, 12, 30)
    return str(delta.days)

方案2:统一类型转换逻辑,消除dtype差异

修改函数,确保输出的dtype与测试用例一致:

def create_combo_npi_and_date_col(data: pd.DataFrame, date_name: str = 'Date') -> pd.DataFrame:
    temp = data.copy()
    days_since_1899 = temp[date_name].apply(days_since_dec_30_1899)
    
    # 统一处理NPI类型,保持输出为object dtype
    if pd.api.types.is_float_dtype(temp['NPI']):
        temp['NPI'] = temp['NPI'].astype('Int64').astype(str)
    else:
        temp['NPI'] = temp['NPI'].astype(str)
    
    # 生成Combo列,用replace替换<NA>,避免元素类型混合
    temp['Combo (NPI & Date)'] = temp['NPI'] + days_since_1899
    temp['Combo (NPI & Date)'] = temp['Combo (NPI & Date)'].replace('<NA>', np.nan)
    
    return temp

方案3:调整测试用例(或忽略dtype检查)

如果确认业务逻辑中dtype差异不影响结果,可以在测试时关闭dtype检查:

# Test 1
self.assertTrue(output.equals(create_combo_npi_and_date_col(input), check_dtype=False), 'test 1 has failed')
# Test 2
self.assertTrue(output.equals(create_combo_npi_and_date_col(input), check_dtype=False), 'test 2 has failed')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 08:24:19