如何根据列值是否在指定列表中创建两个子DataFrame
问题需求
现有通过以下代码读取的DataFrame:
import pandas as pd Data = pd.read_csv('info_com.csv') df1 = pd.DataFrame(Data)
该DataFrame包含名为Code的列,存储产品代码及对应产品的全部信息。需要将其拆分为两个子DataFrame:
- 一个包含合格代码(存在于目标列表
goodCodes中)对应的所有行 - 另一个包含不合格代码(不在目标列表中)对应的所有行
原尝试的循环实现代码存在问题,无法正确生成目标DataFrame:
ComDF1 = df1['Codes'] # 注意:原问题中DataFrame列名为'Code',此处存在笔误 goodCodes = ['B0CD3589HR', ..., 'B0CD726Q8T'] # 原代码未初始化目标DataFrame,直接append会报错 dfWP = pd.DataFrame() dfNWP = pd.DataFrame() for i in range(len(ComDF1)): if ComDF1[i] in goodCodes: df1.iloc[i].append(dfWP) else: df1.iloc[i].append(dfNWP) print(dfWP, dfNWP)
问题分析
原代码存在几个关键问题:
- 列名不一致:原DataFrame的目标列是
Code,但代码中错误取了df1['Codes'] - 未初始化目标DataFrame,直接调用
append会触发报错 - 使用
Series.append()方法错误:该方法用于拼接Series,而非往DataFrame中添加行 - 循环遍历行的方式效率极低,不符合pandas矢量化操作的最佳实践
正确实现方式
方法一:布尔索引(推荐,性能最优)
利用isin()生成布尔掩码,直接筛选目标行:
import pandas as pd # 读取数据 df1 = pd.read_csv('info_com.csv') # 合格代码列表 goodCodes = ['B0CD3589HR', 'B0CD726Q8T'] # 替换为你的完整列表 # 筛选合格代码对应的行 df_good = df1[df1['Code'].isin(goodCodes)] # 筛选不合格代码对应的行(~表示取反布尔掩码) df_bad = df1[~df1['Code'].isin(goodCodes)] # 查看结果 print("合格代码数据:") print(df_good) print("\n不合格代码数据:") print(df_bad)
方法二:query()方法(语法更简洁)
# 筛选合格代码 df_good = df1.query('Code in @goodCodes') # 筛选不合格代码 df_bad = df1.query('Code not in @goodCodes')
注意事项
- 如果原DataFrame的目标列确实是
Codes(而非Code),只需将代码中的'Code'替换为'Codes'即可 - 两种方法均无需手动初始化空DataFrame,直接通过掩码筛选一步到位,处理大数据集时性能远优于循环遍历
内容的提问来源于stack exchange,提问作者melgibsonuwu
相关产品推荐
相关产品推荐

