如何在Python DataFrame中为每行生成指定列的前三最大值列?
解决方法:获取每行第二、第三大值
你可以通过两种高效方式实现提取每行的第二、第三大值,以下是具体方案:
方案1:用numpy.partition(无需全排序,性能更优)
np.partition能快速定位第k大元素,适合处理此类问题:
import numpy as np import pandas as pd data = { 'Name': ['Tom', 'nick', 'krish', 'jack'], 'A': [20, 21, 19, 18], 'B': [3, 6, 2, 1], 'C': [6, 14, 5, 17], 'D': [2, 10, 9, 98] } people = pd.DataFrame(data) target_cols = ['A', 'B', 'C', 'D'] # 已实现的最大值列 people['max_1'] = people[target_cols].max(axis=1) # 提取第二大值:partition后取倒数第2个元素 people['max_2'] = np.partition(people[target_cols].values, -2, axis=1)[:, -2] # 提取第三大值:partition后取倒数第3个元素 people['max_3'] = np.partition(people[target_cols].values, -3, axis=1)[:, -3] print(people)
方案2:排序后直接提取(逻辑直观)
对每行元素降序排序后,取对应索引的元素:
sorted_vals = people[target_cols].apply(lambda x: x.sort_values(ascending=False).values, axis=1) people['max_2'] = sorted_vals.str[1] people['max_3'] = sorted_vals.str[2]
运行后输出结果:
Name A B C D max_1 max_2 max_3 0 Tom 20 3 6 2 20 6 3 1 nick 21 6 14 10 21 14 10 2 krish 19 2 5 9 19 9 5 3 jack 18 1 17 98 98 18 17
附加问题:添加条件判断
要实现仅对Name为'Tom'/'nick'/'krish'的行计算,其余行设为0,可通过以下两种方式:
方法1:用np.where批量赋值
mask = people['Name'].isin(['Tom', 'nick', 'krish']) people['max_1'] = np.where(mask, people[target_cols].max(axis=1), 0) people['max_2'] = np.where(mask, np.partition(people[target_cols].values, -2, axis=1)[:, -2], 0) people['max_3'] = np.where(mask, np.partition(people[target_cols].values, -3, axis=1)[:, -3], 0)
方法2:布尔索引精准赋值
# 先初始化所有值为0 people[['max_1', 'max_2', 'max_3']] = 0 filtered_rows = people[mask] people.loc[mask, 'max_1'] = filtered_rows[target_cols].max(axis=1) people.loc[mask, 'max_2'] = np.partition(filtered_rows[target_cols].values, -2, axis=1)[:, -2] people.loc[mask, 'max_3'] = np.partition(filtered_rows[target_cols].values, -3, axis=1)[:, -3]
运行后输出结果:
Name A B C D max_1 max_2 max_3 0 Tom 20 3 6 2 20 6 3 1 nick 21 6 14 10 21 14 10 2 krish 19 2 5 9 19 9 5 3 jack 18 1 17 98 0 0 0
内容的提问来源于stack exchange,提问作者Naor
相关产品推荐
相关产品推荐

