对比主列表与DataFrame列时遇索引不兼容错误,求解决方法
问题解决:DataFrame提取匹配国家列报错处理
问题背景
原始DataFrame:
Id status countries 01 pass ['xyx','Indonesia','brazil'] 02 fail ['PQ','XT','sri lanka'] 03 pass ['spain', 'india','xtx']
期望生成的DataFrame:
Id status countries filtered_countries_name 01 pass ['xyx','Indonesia','brazil'] 'Indonesia','brazil' 02 fail ['PQ','XT','sri lanka'] 'sri lanka' 03 pass ['spain', 'india','xtx'] 'spain', 'india'
需求是用指定国家主列表匹配countries列,提取符合条件的国家到新列filtered_countries_name,但运行以下代码时出现错误:
countries_list = ['china', 'india', 'united states', 'indonesia', 'brazil', 'pakistan', 'nigeria', 'bangladesh', 'russia', 'japan', 'mexico', 'philippines', 'vietnam', 'ethiopia', 'egypt', 'germany', 'iran', 'turkey', 'democratic republic of the congo', 'thailand', 'france', 'united kingdom', 'italy', 'burma', 'south africa', 'south korea', 'colombia', 'spain', 'ukraine', 'tanzania', 'kenya', 'argentina', 'algeria', 'poland', 'sudan', 'uganda','Indonesia','brazil','spain','sri lanka'] import re countries_re = '|'.join(str(v) for v in countries_list ) df['filtered_countries_name'] = df['countries'].str.extractall(countries_re)
错误信息:
TypeError: incompatible index of inserted column with frame index
错误原因
str.extractall()会返回一个多层索引的DataFrame(外层是原DataFrame的索引,内层是每个匹配项的序号),而原DataFrame是单层索引,直接将多层索引的结果赋值给新列时,索引结构不匹配,导致报错。
解决思路与实现代码
方案1:使用str.findall()直接提取并合并
str.findall()会返回每个行的匹配结果列表,后续通过str.join()将列表转为字符串,索引与原DataFrame完全匹配,不会出现索引冲突。
import re import pandas as pd # 清理国家列表:去重,避免重复匹配 countries_list = list(set([ 'china', 'india', 'united states', 'indonesia', 'brazil', 'pakistan', 'nigeria', 'bangladesh', 'russia', 'japan', 'mexico', 'philippines', 'vietnam', 'ethiopia', 'egypt', 'germany', 'iran', 'turkey', 'democratic republic of the congo', 'thailand', 'france', 'united kingdom', 'italy', 'burma', 'south africa', 'south korea', 'colombia', 'spain', 'ukraine', 'tanzania', 'kenya', 'argentina', 'algeria', 'poland', 'sudan', 'uganda','Indonesia','brazil','spain','sri lanka' ])) # 构建正则表达式:转义特殊字符,添加忽略大小写标记 countries_re = '|'.join([re.escape(c) for c in countries_list]) # 提取所有匹配项,合并为指定格式的字符串 df['filtered_countries_name'] = df['countries'].str.findall(countries_re, flags=re.IGNORECASE).str.join("','") # 给结果包裹外层单引号 df['filtered_countries_name'] = "'" + df['filtered_countries_name'] + "'"
方案2:基于extractall()分组聚合
如果必须使用extractall(),可以通过分组聚合将多层索引的结果合并为单层索引的Series,再赋值给新列:
import re import pandas as pd # 清理国家列表(同方案1) countries_list = list(set([ 'china', 'india', 'united states', 'indonesia', 'brazil', 'pakistan', 'nigeria', 'bangladesh', 'russia', 'japan', 'mexico', 'philippines', 'vietnam', 'ethiopia', 'egypt', 'germany', 'iran', 'turkey', 'democratic republic of the congo', 'thailand', 'france', 'united kingdom', 'italy', 'burma', 'south africa', 'south korea', 'colombia', 'spain', 'ukraine', 'tanzania', 'kenya', 'argentina', 'algeria', 'poland', 'sudan', 'uganda','Indonesia','brazil','spain','sri lanka' ])) countries_re = '|'.join([re.escape(c) for c in countries_list]) # 提取所有匹配项,按原索引分组合并 extracted_df = df['countries'].str.extractall(f'({countries_re})', flags=re.IGNORECASE) filtered_series = extracted_df.groupby(level=0)[0].apply(lambda x: "','".join(x)) # 赋值给新列,空值填充为空字符串(可选) df['filtered_countries_name'] = "'" + filtered_series.fillna('') + "'"
关键注意点
- 国家列表去重:原列表存在重复项(如
Indonesia和indonesia),去重后可避免重复匹配。 - 正则转义:使用
re.escape()处理国家名中的特殊字符(如空格、连字符),避免正则语法错误。 - 忽略大小写:添加
flags=re.IGNORECASE确保匹配不区分大小写(如匹配Indonesia和indonesia)。
内容的提问来源于stack exchange,提问作者Romi
相关产品推荐
相关产品推荐

