如何更优实现基于条件删除Pandas DataFrame前3列对应行并插入至同表新行?
优化方案实现你的需求
首先得明确你的核心需求:筛选出Match1列值为"No"的行,将这些行从原DataFrame的对应位置移除,再把它们追加到DataFrame的末尾。你的当前实现存在几个可以优化的点,比如不必要的空中间DataFrame创建、使用了已被弃用的append方法(pandas 2.0+官方推荐用pd.concat),而且筛选逻辑和你描述的“Match1为No”需求不匹配(你当前用的是Name=='Ole'作为筛选条件)。
简洁高效的实现步骤
我们可以把操作拆分为三个清晰的步骤:筛选待移动行、保留剩余行、合并两者得到结果,代码如下:
import pandas as pd # 原始DataFrame df2 = pd.DataFrame({ 'Name':['John', 'Tom', 'Tom' ,'Ole','Ole','Tom'], 'SomeQty':[100, 200, 300, 500,600, 400], 'Match':['Yes', 'No', 'Yes','No','No','No'], 'SomeValue':[100, 200, 200, 500, 600, 200], 'Match1':['Yes', 'Yes','Yes', 'No','No', 'Yes'], }) # 1. 筛选出Match1为"No"的待移动行 to_move = df2[df2['Match1'] == 'No'].copy() # 2. 保留原DataFrame中不需要移动的行 remaining = df2[df2['Match1'] != 'No'].copy() # 3. 合并剩余行和待移动行,生成最终结果 result_df = pd.concat([remaining, to_move], ignore_index=True) print(result_df)
代码优势说明
- 精准匹配需求:直接用
df2['Match1'] == 'No'作为筛选条件,完全贴合你描述的规则,避免了按Name筛选的偏差 - 符合现代pandas规范:使用
pd.concat替代已弃用的append方法,性能更优且兼容性更好 - 逻辑清晰易懂:拆分步骤后代码可读性强,不需要额外创建空的中间DataFrame
- 数据完整性:默认保留所有列的完整性,如果你确实需要仅处理前3列+Match1列,也可以在筛选时指定列,比如
to_move = df2.loc[df2['Match1'] == 'No', ['Name', 'SomeQty', 'Match', 'Match1']].copy(),合并时注意列对齐即可
针对“删除前3列中对应行”的补充实现
如果你实际需求是仅清空原DataFrame中Match1为No的行的前3列数据,再把完整的这些行追加到末尾,可以用下面的代码:
# 标记待移动行的索引 move_indices = df2[df2['Match1'] == 'No'].index # 复制待移动的完整行 to_move = df2.loc[move_indices].copy() # 清空原DataFrame中这些行的前3列数据 df2.loc[move_indices, df2.columns[:3]] = pd.NA # 合并处理后的原DataFrame和待移动行 result_df = pd.concat([df2, to_move], ignore_index=True)
从你的原始代码逻辑来看,第一种整行移动的方案更符合你想要的效果——把Match1为No的行从原位置移除,放到DataFrame的末尾。
内容的提问来源于stack exchange,提问作者Klllmmm




