如何在熊猫数据框的每一行中找到选定列中的两个最低值?
Posted
技术标签:
【中文标题】如何在熊猫数据框的每一行中找到选定列中的两个最低值?【英文标题】:How do I find the two lowest values across selected columns in each row of a pandas dataframe? 【发布时间】:2020-10-26 23:29:13 【问题描述】:在计算成绩时,我会去掉每个学生的两个最低作业分数。此处显示了一个示例数据框:
df=pd.DataFrame([[10, 9, 10, 5, 7], [8, 7, 9, 9, 4], [10, 10, 7, 0, 8],
[5, 9, 7, 6, 3], [10, 5, 0, 8, 10], [8, 9, 10, 10, 10]],
columns=['HW1', 'HW2', 'HW3', 'HW4', 'HW5'],
index=['Aaron', 'Bridget', 'Charles', 'Donna', 'Evan', 'Francesca'])
df
实际的数据框包含比这更多的列(用于测试、报告等),但这是家庭作业,我需要找到每条记录的两个最低分数。
我想在数据框中添加两列 ['Lowest'] 和 ['Second_Lowest'],并在这些列中分别指示每个学生的最低分数和次低分数。
我尝试了以下代码,使用 .min() 方法获取最小值,但出现错误:
df['Lowest_HW'] = df[['HW1', 'HW2', 'HW3', 'HW4', 'HW5']].min()
df.head()
所以对于 Aaron,Lowest 的值为 5,Second_Lowest 的值为 7;对于 Francesca,Lowest 为 8,Second_Lowest 为 9。
显然,.min() 方法的代码不正确,我完全不知道要找到第二低的值。
对我如何处理这些步骤有什么建议吗?
【问题讨论】:
您的最低代码几乎是正确的,但是您需要.min(axis=1)
将min
应用于行而不是列。
@ALollz:这是个好问题。我想要单独列中的最低值的原因是因为我要创建一个总作业分数列,该列将是所有 5 个作业列的总和,减去 Lowest 和 Second_Lowest,所以我确实想调出它们的两个最低作业值.
【参考方案1】:
您可以使用 np.sort
并仅选择前 2 列来同时创建最低的两列:
df['lowest'], df['second_lowest'] = np.sort(df, axis=1)[:, :2].T
print (df)
HW1 HW2 HW3 HW4 HW5 lowest second_lowest
Aaron 10 9 10 5 7 5 7
Bridget 8 7 9 9 4 4 7
Charles 10 10 7 0 8 0 7
Donna 5 9 7 6 3 3 5
Evan 10 5 0 8 10 0 5
Francesca 8 9 10 10 10 8 9
但是如果你的意思是在没有这两个最低值的情况下得到总和,那么不要创建上面的列并做
df['sum_without_2lowest'] = np.sort(df, axis=1)[:, 2:].sum(1)
print (df)
HW1 HW2 HW3 HW4 HW5 sum_without_2lowest
Aaron 10 9 10 5 7 29
Bridget 8 7 9 9 4 26
Charles 10 10 7 0 8 28
Donna 5 9 7 6 3 22
Evan 10 5 0 8 10 28
Francesca 8 9 10 10 10 30
【讨论】:
【参考方案2】:又是另一种方法,使用nsmallest
。这次它直接从DataFrame中移除了两个最低等级
df[df.apply(lambda x: x.nsmallest(2), axis=1).isna()]
HW1 HW2 HW3 HW4 HW5
Aaron 10.0 9.0 10.0 NaN NaN
Bridget 8.0 NaN 9.0 9.0 NaN
Charles 10.0 10.0 NaN NaN 8.0
Donna NaN 9.0 7.0 6.0 NaN
Evan 10.0 NaN NaN 8.0 10.0
Francesca NaN NaN 10.0 10.0 10.0
正如您在 cmets 中提到的,您想要获得所有成绩的总和减去两个最低成绩的总和,这可以轻松解决问题!
df[df.apply(lambda x: x.nsmallest(2), axis=1).isna()].sum(axis=1)
Aaron 29.0
Bridget 26.0
Charles 28.0
Donna 22.0
Evan 28.0
Francesca 30.0
dtype: float64
【讨论】:
【参考方案3】:您可以使用apply
来执行此操作,对列进行排序并选择第一个和第二个值。
columns = [c for c in df.columns if c.startswith('HW')]
df[['lowest', '2nd_lowest']] = df[columns].apply(lambda x: sorted(x)[0:2], axis=1, result_type='expand')
HW1 HW2 HW3 HW4 HW5 lowest 2nd_lowest
Aaron 10 9 10 5 7 5 7
Bridget 8 7 9 9 4 4 7
Charles 10 10 7 0 8 0 7
Donna 5 9 7 6 3 3 5
Evan 10 5 0 8 10 0 5
Francesca 8 9 10 10 10 8 9
【讨论】:
以上是关于如何在熊猫数据框的每一行中找到选定列中的两个最低值?的主要内容,如果未能解决你的问题,请参考以下文章