Pandas在含字典列表的列中搜索指定字符串无结果,求解决方法及原因
Pandas筛选嵌套字典列表列的问题
问题背景
现有一个Pandas DataFrame,其中sigResponseActions列的每个元素是包含字典的列表,示例数据如下:
[ {'@odata.type': '#microsoft.graph.security.collectInvestigationPackageResponseAction', 'identifier': 'deviceId'}, {'@odata.type': '#microsoft.graph.security.runAntivirusScanResponseAction', 'identifier': 'deviceId'}, {'@odata.type': '#microsoft.graph.security.stopAndQuarantineFileResponseAction', 'identifier': 'deviceId,sha1'} ]
需要筛选出该列中包含stopAndQuarantineFileResponseAction或softDeleteResponseAction的所有行,但以下两种方法均未得到结果:
方法一(无效)
strings = ['stopAndQuarantineFileResponseAction', 'softDeleteResponseAction'] filtered_df = df[df['SigResponseActions'].isin(strings)] filtered_df
方法二(无效)
df1 = df[df['SigResponseActions'].str.contains('stopAndQuarantineFileResponseAction',na=False)] df1.head(5)
无效原因分析
- 方法一问题:
isin()方法用于检查整个列元素是否完全匹配列表中的值,但sigResponseActions列的元素是列表嵌套字典,不是单个字符串,完全匹配不可能成立,因此返回空结果。 - 方法二问题:
str.contains()是Series的字符串处理方法,仅适用于字符串类型的元素。当列元素是列表对象时,调用该方法会将列表强制转为字符串,但默认会对非字符串元素返回NaN,加上na=False后会直接排除这些行,最终得到空结果。
解决方法
方法1:使用apply遍历检查(推荐)
通过apply遍历每行的列表,检查列表中是否存在字典的@odata.type包含目标字符串:
targets = ['stopAndQuarantineFileResponseAction', 'softDeleteResponseAction'] filtered_df = df[df['sigResponseActions'].apply( lambda row_list: any(target in item['@odata.type'] for item in row_list) )]
- 逻辑:对每行的列表
row_list,遍历其中的每个字典item,检查@odata.type字段是否包含任意一个目标字符串,只要有一个满足就返回True,从而筛选出符合条件的行。
方法2:先展开列表再筛选
如果需要查看具体匹配的字典项,可以先将列表展开为单行,筛选后再还原:
targets = ['stopAndQuarantineFileResponseAction', 'softDeleteResponseAction'] # 将列表展开,每个字典单独占一行 exploded_df = df.explode('sigResponseActions') # 筛选符合条件的行 matched_rows = exploded_df[exploded_df['sigResponseActions'].apply( lambda item: any(target in item['@odata.type'] for target in targets) )] # 去重还原为原数据结构 filtered_df = matched_rows.drop_duplicates(subset=df.columns)
内容的提问来源于stack exchange,提问作者Dirk Pitt
相关产品推荐
相关产品推荐

