如何按条件对DataFrame数值列排名:ID分组与Variable_1判断规则
解决Pandas分组条件排名问题
需求说明
按ID列分组后:
- 当
Variable_1值为True时,对Number列做降序密集排名 - 当
Variable_1值为False时,新列Rank直接赋值为1
示例数据
import pandas as pd import numpy as np data={'ID':["A","A","B","C","D","D"], 'Variable_1':[True,True,False,False,True,True], 'Number': [10,20,5,6,100,90]} df=pd.DataFrame(data)
错误代码分析
你尝试的代码会报错,原因有两点:
df.groupby(["ID"])[["Number"]].rank(...)返回的是DataFrame,而np.where要求第二个参数必须是与原DataFrame长度匹配的Series,类型不兼容- 直接对全量数据做分组排名,没有限定仅对
Variable_1=True的行生效,逻辑不符合需求
df["Rank"] = np.where(df.Variable_1, df.groupby(["ID"])[["Number"]].rank(method='dense', ascending=False), 1)
正确解法
方法一:简洁版(用where方法)
先对全量数据按ID分组做Number列的降序密集排名,再用where保留Variable_1=True的排名结果,其余替换为1:
df['Rank'] = df.groupby('ID')['Number'].rank(method='dense', ascending=False).where(df['Variable_1'], 1)
方法二:直观版(分步赋值)
先初始化Rank列为1,再筛选出Variable_1=True的行单独做分组排名并赋值:
# 初始化Rank列为1 df['Rank'] = 1 # 筛选目标行并赋值排名结果 mask = df['Variable_1'] == True df.loc[mask, 'Rank'] = df[mask].groupby('ID')['Number'].rank(method='dense', ascending=False)
预期输出
执行正确代码后,DataFrame结果如下:
ID Variable_1 Number Rank 0 A True 10 2.0 1 A True 20 1.0 2 B False 5 1.0 3 C False 6 1.0 4 D True 100 1.0 5 D True 90 2.0
内容的提问来源于stack exchange,提问作者the phoenix
相关产品推荐
相关产品推荐

