基于发票号匹配为DataFrame新增列赋值的Pandas实现问题
问题解决:DataFrame根据发票号列表生成新列
我有一个DataFrame和一份唯一发票号码列表,想要遍历DataFrame,检查每行的InvoiceNo是否在这个列表里,存在的话给新建的NEWCOLUMN列赋值0,不存在则赋值1。用.iterrows()尝试的时候始终报错,环境是Python 3.9.13、Pandas 1.4.4,求指导。
数据示例
InvoiceNo StockCode ....... UnitPrice CustomerID NEWCOLUMN 536365 85123A 2.55 17850 536366 22633 1.85 17850 536372 84879 1.69 13047
尝试的错误代码
new_list = [] for i, row in df.iterrows(): if df[i, 'InvoiceNo'] in comparison_list: df[i, 'NEWCOLUMN'] = 0 else: df[i, 'NEWCOLUMN'] = 1
问题分析与解决方案
错误点说明
- 行数据访问错误:
df[i, 'InvoiceNo']不是正确的行值获取方式,iterrows()返回的row是当前行的Series,应该用row['InvoiceNo']获取当前行的发票号。 - 赋值方式错误:直接用
df[i, 'NEWCOLUMN']修改会触发警告且效率极低,Pandas不推荐在循环中直接修改原DataFrame。
推荐方法:矢量化操作(性能最优)
用Pandas内置的isin()方法批量判断,再转成0/1值,这是Pandas的标准高效写法:
# 方法1:用~取反后转int(True→1,False→0) df['NEWCOLUMN'] = (~df['InvoiceNo'].isin(comparison_list)).astype(int) # 方法2:用np.where更直观,明确指定条件结果 import numpy as np df['NEWCOLUMN'] = np.where(df['InvoiceNo'].isin(comparison_list), 0, 1)
循环写法修复(仅作语法参考,不推荐)
如果一定要用循环实现,修正语法如下:
# 先初始化列,避免赋值时的索引问题 df['NEWCOLUMN'] = 0 for idx, row in df.iterrows(): if row['InvoiceNo'] not in comparison_list: df.loc[idx, 'NEWCOLUMN'] = 1
内容的提问来源于stack exchange,提问作者Wildo_Baggins311
相关产品推荐
相关产品推荐

