pandas版本更新后原有代码无法运行,触发.str访问器AttributeError报错
问题原因与解决方案
错误原因
这个报错是pandas版本迭代后对访问器的校验逻辑收紧导致的:
- 旧版本pandas允许在混有非字符串值的object类型列、甚至datetime类型列上调用
.str访问器,不符合条件的内容只会返回NaN不会抛出显性错误 - 新版本(pandas 1.0及以上)仅允许明确为字符串类型(string dtype)、或全为字符串的object类型列调用
.str访问器,你的service_date列大概率是升级后被自动推断为datetime类型,或是列中存在非字符串内容,导致调用.str.contains时报错。
解决方法
你可以根据你的列实际类型选择对应方案:
方案1:service_date为datetime类型(推荐)
直接使用datetime专属的.dt访问器筛选年份,比字符串匹配效率更高、准确性更强,修改筛选逻辑即可:
iterator = ['18', '19', '20', '21'] # 建议用字典存储动态生成的DataFrame,比直接写locals()更易维护且无变量污染问题 list1_store = {} list2_store = {} for i in iterator: target_year = int(f"20{i}") list1_store[f"List1_20{i}"] = List1[List1['service_date'].dt.year == target_year] list2_store[f"List2_20{i}"] = list1_store[f"List1_20{i}"][ list1_store[f"List1_20{i}"]['is_provider_server'] == 'YES' ].groupby(['provider_number'])['is_provider_server'].count().reset_index().rename(columns={'is_provider_server': "provider_server"})
方案2:service_date为object类型存在非字符串值
如果确实需要用字符串匹配的方式筛选,先强制将列转为字符串类型再调用.str访问器:
iterator = ['18', '19', '20', '21'] list1_store = {} list2_store = {} for i in iterator: list1_store[f"List1_20{i}"] = List1[List1['service_date'].astype(str).str.contains(f"20{i}-")] list2_store[f"List2_20{i}"] = list1_store[f"List1_20{i}"][ list1_store[f"List1_20{i}"]['is_provider_server'] == 'YES' ].groupby(['provider_number'])['is_provider_server'].count().reset_index().rename(columns={'is_provider_server': "provider_server"})
如果坚持要使用locals()生成全局变量,只需要替换筛选行的List1['service_date'].str.contains部分为对应方案的代码即可。
内容的提问来源于stack exchange,提问作者Raul A. Ocasio Gonzalez
相关产品推荐
相关产品推荐

