如何按位置(loc)删除Pandas DataFrame行(非按索引)
问题描述
现有一个整数索引(有序且唯一,但存在缺失值)的pandas.DataFrame,已确定部分需删除的行,同时要删除每个目标行的下一行(其索引无法直接确定)。目前已将待删除行的索引转换为位置列表[0,1,4,5],需要实现按该列表删除行以得到预期结果。
代码示例
import pandas as pd import numpy as np # 构建标识列 identifier_1 = pd.Series([True]*3, index=[1, 5, 9]) identifier_2 = pd.Series([True]*3, index=[3, 8, 11]) # 构建带索引的DataFrame df = pd.DataFrame( { 'data':[0, 1, 3, 7, 8, 12, 13, 15, 16, 18, 25, 28, 29] }, index=np.arange(13)) # 合并标识列到DataFrame df = df.merge(identifier_1.rename('ident_1'), how='left', left_index=True, right_index=True) df = df.merge(identifier_2.rename('ident_2'), how='left', left_index=True, right_index=True) df = df.fillna(value=False) # 筛选出ident_1或ident_2为True的行 relev_df = df.loc[df["ident_1"] | df["ident_2"], :] # 创建判断列 relev_df['criteria'] = np.where(relev_df.ident_1, relev_df.data.diff(periods=-1), np.NaN) criteria_value = -5 # 获取不符合条件的索引列表 index_ident1 = relev_df[relev_df['criteria'] < criteria_value].index index_ident1 = [x for x in index_ident1] # 将索引转换为位置列表 loc_ident_1 = [] unique_index = relev_df.index for idx in index_ident1: _loc = unique_index.get_loc(idx) loc_ident_1.extend((_loc, _loc + 1))
当前中间结果
df: data ident_1 ident_2 0 0 False False 1 1 True False 2 3 False False 3 7 False True 4 8 False False 5 12 True False 6 13 False False 7 15 False False 8 16 False True 9 18 True False 10 25 False False 11 28 False True 12 29 False False relev_df: data ident_1 ident_2 criteria 1 1 True False -6.0 3 7 False True NaN 5 12 True False -4.0 8 16 False True NaN 9 18 True False -10.0 11 28 False True NaN identified indexes: [1, 9] identified locations: [0, 1, 4, 5]
预期结果
result_df: data ident_1 ident_2 criteria 5 12 True False -4.0 8 16 False True NaN
解决方案
直接利用pandas的索引定位功能,通过待删除的位置列表筛选出需要保留的行即可,有两种简洁实现方式:
方法一:通过iloc和布尔索引
import numpy as np # 生成所有行的位置数组 all_positions = np.arange(len(relev_df)) # 筛选出不在待删除列表中的位置 keep_positions = all_positions[~np.isin(all_positions, loc_ident_1)] # 获取结果 result_df = relev_df.iloc[keep_positions]
方法二:直接使用drop方法
# 通过位置获取对应的行索引,然后删除这些行 result_df = relev_df.drop(relev_df.index[loc_ident_1])
两种方法都能得到符合预期的result_df。
内容的提问来源于stack exchange,提问作者Mark TeaBot
相关产品推荐
相关产品推荐

