基于排序结果的DataFrame数据过滤:多条件去重需求求解
解决方案:按CLASS筛选并优先选取EXPIRY、VOLUME最大值的记录
这是一个典型的分组优先级筛选需求,你只需要调整排序逻辑,把VOLUME也纳入排序优先级,就能完美解决问题。下面提供两种符合Python/Pandas风格的实现方案:
方案一:排序+去重(高效简洁,推荐)
这种方法通过多字段降序排序,让每个CLASS下符合要求的记录排在最前面,再去重保留第一条,性能更优,适合处理大数据集:
import pandas as pd # 构造示例数据 data = { 'ID': [1,2,3,4,5,6,7], 'CLASS': ['012345','987654','012345','012345','987654','012345','987654'], 'CLASS_ID': ['12','99','11','10','24','06','08'], 'EXPIRY': [70,10,70,60,20,70,60], 'VOLUME': [100,800,200,700,300,900,500] } df = pd.DataFrame(data) # 按CLASS降序、EXPIRY降序、VOLUME降序排序 df_sorted = df.sort_values( by=['CLASS', 'EXPIRY', 'VOLUME'], ascending=[False, False, False] ) # 按CLASS去重,保留第一条(即排序后优先级最高的记录) df_result = df_sorted.drop_duplicates(subset=['CLASS']) # 可选:重置索引让结果更整洁 df_result = df_result.reset_index(drop=True) print(df_result)
执行后输出结果:
ID CLASS CLASS_ID EXPIRY VOLUME 0 7 987654 08 60 500 1 6 012345 06 70 900
逻辑说明:
- 排序时,先按
CLASS分组排序(降序只是为了让结果里987654排在前面,和你的期望输出一致,改成升序也不影响最终筛选逻辑); - 同一
CLASS内,先按EXPIRY降序,把过期值最大的记录排在前面; - 同一
EXPIRY的记录里,再按VOLUME降序,让体积最大的记录排在最顶端; - 最后按
CLASS去重,保留第一条记录,就是每个CLASS下优先级最高的那条。
方案二:GroupBy分组筛选(逻辑直观)
如果你更看重代码的可读性,也可以用groupby分组后,对每个组单独筛选符合条件的记录:
import pandas as pd data = { 'ID': [1,2,3,4,5,6,7], 'CLASS': ['012345','987654','012345','012345','987654','012345','987654'], 'CLASS_ID': ['12','99','11','10','24','06','08'], 'EXPIRY': [70,10,70,60,20,70,60], 'VOLUME': [100,800,200,700,300,900,500] } df = pd.DataFrame(data) # 按CLASS分组,筛选每个组内EXPIRY最大且VOLUME最大的记录 df_result = df.groupby('CLASS').apply( lambda group: group.loc[ (group['EXPIRY'] == group['EXPIRY'].max()) & (group['VOLUME'] == group['VOLUME'].max()) ] ).reset_index(drop=True) print(df_result)
逻辑说明:
- 按
CLASS对DataFrame分组; - 对每个分组,先筛选出
EXPIRY等于组内最大值的所有行; - 再从这些行里筛选出
VOLUME等于组内最大值的行; - 最后合并所有分组的结果,重置索引得到最终数据。
注意:如果某个组内存在多条
EXPIRY和VOLUME都相同的最大值记录,这种方法会保留所有符合条件的记录;而方案一则只会保留排序后的第一条,你可以根据实际需求选择。
内容的提问来源于stack exchange,提问作者Phillip
相关产品推荐
相关产品推荐

