如何根据列值匹配结果将pandas DataFrame指定行移动到末尾
实现方案
完全可以实现,核心逻辑是通过自定义排序规则,将col1值不在list1中的行优先级设为更高排在前列,属于list1的行优先级更低排在末尾即可,以下是两种常用实现方式:
方法1:新增辅助列排序(兼容所有pandas版本)
这种方式逻辑直观,不需要考虑pandas版本限制:
import pandas as pd # 假设你已经构造好df和list1如下: # df = pd.DataFrame({'col1': [10,20,30,40,50], 'col2': [56.4,45.6,12.1,55.4,10.1], 'col3': [78.2,23.3,26.0,22.9,98.3]}) # list1 = [10, 30] # 新增辅助列标记行是否属于list1 df['is_in_list'] = df['col1'].isin(list1) # 先按辅助列升序(False=0在前,True=1在后),再按col1升序排序,最后删除辅助列、重置索引 df_sorted = df.sort_values(by=['is_in_list', 'col1']).drop(columns='is_in_list').reset_index(drop=True)
输出结果和你要求的完全一致:
| col1 | col2 | col3 |
|---|---|---|
| 20 | 45.6 | 23.3 |
| 40 | 55.4 | 22.9 |
| 50 | 10.1 | 98.3 |
| 10 | 56.4 | 78.2 |
| 30 | 12.1 | 26.0 |
方法2:用sort_values的key参数简化写法(pandas ≥ 1.1.0版本支持)
不需要新增辅助列,直接在排序时传入自定义规则即可:
df_sorted = df.sort_values( by='col1', key=lambda col: col.isin(list1).replace({False: 0, True: 1}) ).reset_index(drop=True)
扩展需求:属于list1的行按list1的自定义顺序排列
如果要求末尾的行按照list1中的顺序排布(比如list1为[30,10]时,30排在10前面),可以调整排序规则如下:
# 构造list1的顺序映射 order_dict = {val: idx for idx, val in enumerate(list1)} df_sorted = df.sort_values( by='col1', key=lambda col: col.map(lambda x: (0, x) if x not in order_dict else (1, order_dict[x])) ).reset_index(drop=True)
内容的提问来源于stack exchange,提问作者Denver Dang
相关产品推荐
相关产品推荐

