Pandas列已转字符串仍报.str访问器仅适用字符串值错误排查
问题描述
从FDA网页提取表格信息时使用如下代码:
import pandas as pd # 读取CEDI网页表格 CEDI_inv_url = "https://www.accessdata.fda.gov/scripts/sda/sdNavigation.cfm?sd=edisrev&displayAll=true" CEDI_HTML_tables = pd.read_html(CEDI_inv_url) # 提取目标表格数据 CEDI_table_data = CEDI_HTML_tables[0] CEDI_df = pd.DataFrame (CEDI_table_data, columns = ['MAINTERM','CAS NO','CUM DC (ppb)','CEDI','REGNUM']) CEDI_df['CAS NO'].to_string() # 正则提取CAS号 CEDI_df['CAS NO'] = CEDI_df['CAS NO'].str.extract(r'([0-9]+[\u2011|-][0-9]{2}[\u2011|-][0-9](?![0-9]))') CEDI_df.head()
运行时报错:Can only use .str accessor with string values!,尝试过多种转换列字符串类型的方案均未解决,以下是可落地的排查与解决思路。
排查思路
- 先确认列内值的真实类型:执行
print(CEDI_df['CAS NO'].dtype)查看列声明类型,再执行print(CEDI_df['CAS NO'].apply(type).value_counts())统计列内所有元素的实际类型。多数情况下列内混合了数值、None/NaN类型值,即使列dtype显示为object,存在非字符串值就会导致.str访问器调用失败。 - 检查无效的类型转换代码:代码中
CEDI_df['CAS NO'].to_string()仅会将列内容转换为字符串后返回打印结果,不会对原DataFrame的列做任何修改,属于完全无效的类型转换操作,这是高频踩坑点。 - 确认
read_html的自动类型转换逻辑:pandas的read_html方法默认会自动识别列类型,遇到纯数字格式的内容、空值时,会自动将列转为浮点/整数类型,不会保留原始字符串格式。
解决方案
- 源头规避类型问题:调用
read_html时直接指定列类型,避免自动转码:
CEDI_HTML_tables = pd.read_html(CEDI_inv_url, dtype={'CAS NO': str})
- 调用字符串方法前强制统一类型:在执行正则提取前,先处理空值再统一转字符串,避免非字符串值干扰:
# 空值填充为空字符串,全列强制转为字符串类型 CEDI_df['CAS NO'] = CEDI_df['CAS NO'].fillna('').astype(str) # 再执行正则提取操作 CEDI_df['CAS NO'] = CEDI_df['CAS NO'].str.extract(r'([0-9]+[\u2011|-][0-9]{2}[\u2011|-][0-9](?![0-9]))')
- 提取完成后可将匹配结果为空的项重置为NaN,方便后续数据处理。
提示:只要使用pandas的
.str系列方法,必须保证调用对象的所有元素都是字符串类型,任何非字符串值(包括NaN、数值、布尔值)都会触发该报错。
内容的提问来源于stack exchange,提问作者tom
相关产品推荐
相关产品推荐

