如何用更Pythonic的方式在Pandas中实现指定列的自定义排名计算?
问题描述
给定如下DataFrame:
import pandas as pd data = {'col1': ['a', 'b', 'c'], 'col2': [10, 5, 20]} df_sample = pd.DataFrame(data=data)
想要计算col2的排名,编写了如下函数:
def rank_by(df): if df.shape[0] >= 10: df.sort_values(by=['col2']) l = [] for val in df['col2']: rank = (val/df['col2'].max())*10 l.append(rank) df['rank'] = l return df
假设col2对应的行数超过10,请问是否有更Pythonic的方式实现该函数的功能?
优化方案
当然有更简洁、贴合pandas风格的实现方式,核心是用向量化操作替代低效循环,同时修正原函数里的细节问题:
def rank_by(df): if df.shape[0] >= 10: # 原函数sort_values未修改原DataFrame,这里通过赋值+copy避免污染输入数据 df = df.sort_values(by='col2').copy() # 直接对整列做元素级运算,无需手动遍历 df['rank'] = (df['col2'] / df['col2'].max()) * 10 return df
关键优化点:
- 抛弃循环:pandas的Series支持直接进行批量运算,比手动遍历列表高效数倍,代码也更简洁。
- 修正排序逻辑:原函数中
df.sort_values(...)默认不会修改原DataFrame,必须通过赋值或设置inplace=True生效(推荐用赋值+copy,避免意外修改传入的原始数据)。 - 简化赋值流程:不需要手动创建列表再赋值给新列,直接将运算结果赋值给
df['rank']即可完成列的添加。
如果不需要保留原始DataFrame的顺序,也可以进一步简化:
def rank_by(df): if df.shape[0] >= 10: df['rank'] = (df['col2'] / df['col2'].max()) * 10 df.sort_values(by='col2', inplace=True) return df
内容的提问来源于stack exchange,提问作者justanewb
相关产品推荐
相关产品推荐

