为何判断DataFrame列元素存在性仅调用tolist()时生效?
问题
我必须将DataFrame的列转换为列表才能匹配元素。我正尝试创建字典mytable,遍历table_main的每行,当row['apple']不在table3['codes']且不等于"07"时,向mytable添加行。代码如下:
mytable = {'column1' :[] , 'column2':[] , 'column3': [] , 'column4':[]} for index, row in table_main.itterrows(): if row['apple'] not in table3['codes'] and row['apple']!= "07": mytable['column1'].append("2024") mytable['column2'].append(str(row['number'])) mytable['column3'].append(str(row['apple'])) mytable['column4'].append("first condition")
但直接判断row['apple']是否在table3['codes']中无效,仅当调用table3['codes'].tolist()时才生效,想了解原因。
原因解释
这是因为Pandas的Series(也就是你这里的table3['codes'])对in运算符的实现逻辑和Python列表完全不同:
- 当你用
x in Series时,Pandas实际检查的是x是否属于这个Series的索引值,而非x是否存在于Series的元素中。 - 而调用
tolist()把Series转成Python列表后,x in list会遵循原生Python的判断逻辑,检查x是否是列表里的元素,这才是你需要的匹配逻辑。
举个直观的例子:假设table3['codes']是索引为0、1、2,元素为['01','02','03']的Series,那么'01' in table3['codes']会返回False(因为'01'不是索引),但'01' in table3['codes'].tolist()会返回True(因为'01'是列表内的元素)。
另外补充个优化建议:用iterrows()遍历DataFrame的效率极低,推荐用Pandas矢量化操作替代,既不用手动转列表,性能也会提升很多。比如:
# 先构造筛选条件 mask = (~table_main['apple'].isin(table3['codes'])) & (table_main['apple'] != "07") # 筛选符合条件的行 filtered_rows = table_main[mask] # 直接构造目标字典 mytable = { 'column1': ["2024"] * len(filtered_rows), 'column2': filtered_rows['number'].astype(str).tolist(), 'column3': filtered_rows['apple'].astype(str).tolist(), 'column4': ["first condition"] * len(filtered_rows) }
这里的isin()方法是Pandas专门用来检查元素是否存在于另一个Series/列表中的方法,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Melika02
相关产品推荐
相关产品推荐

