对于每个类别,如何找到与另一列的最小值对应的列的值?

Posted

技术标签:

【中文标题】对于每个类别,如何找到与另一列的最小值对应的列的值?【英文标题】:For each category, how to find the value of a column corresponding to the minimum of another column? 【发布时间】:2021-02-05 23:27:46 【问题描述】:

我有一张像这样的桌子;它是交叉表的堆叠版本,因此项目和期间的每个组合都是唯一的:

+------+--------+-------+
| item | period | value |
+------+--------+-------+
| x    |      1 |     6 |
| x    |      2 |     4 |
| x    |      3 |     5 |
| y    |      1 |     9 |
| y    |      2 |    10 |
| y    |      3 |   100 |
+------+--------+-------+

对于每个项目,我需要找到值最低的时段,所以想要的结果是:

+------+--------+-------+
| item | period | value |
+------+--------+-------+
| x    |      2 |     4 |
| y    |      1 |     9 |
+------+--------+-------+

我已经研究过 pandas.DataFrame.idxmin() 但它似乎不是我需要的。 我找到了一种使用 groupby、min 和 merge 的方法,但我想知道是否有更优雅的解决方案?

我发现了许多与 R 和 SQL 相关的类似问题(我的解决方案实际上是“SQLish”,而不是 Python

我的解决办法是:

import numpy as np
import pandas as pd


df = pd.DataFrame()
df['item'] = np.repeat(['x','y'],3)
df['period'] = np.tile( [1,2,3] ,2 )
df['value'] = [6,4,5,9,10,100]


min_value = df[['item','value']].groupby('item').min().reset_index(drop = False)

periods_with_min_value = pd.merge(min_value, df, how ='inner', on=['item','value'])

【问题讨论】:

【参考方案1】:
df.loc[df.groupby("item")["value"].idxmin()]
Out[12]: 
  item  period  value
1    x       2      4
3    y       1      9

在 pandas 1.1.3、python 3.7、debian 10 64 位上测试。没有发出警告。

注意如果存在重复或损坏的索引值,此解决方案将不起作用。这可以通过.reset_index(drop=True)提前解决。

【讨论】:

我已经在我的实际数据上尝试过了,我收到一条关于缺少标签的错误消息,我不明白 - idxmin 是否返回缺少的标签? KeyError:“不再支持将列表喜欢传递给带有任何缺失标签的 .loc 或 []。缺少以下标签:Float64Index([nan, nan, nan, nan], dtype='float64')。见 @987654321 @" 您的索引可能已损坏。也许.reset_index(drop=True) 再试一次?我正在使用 pandas 1.1.3 并且没有发出警告。这个操作对我来说似乎很正常。 原来我有一些行的 value = nan,这就是导致问题的原因

以上是关于对于每个类别,如何找到与另一列的最小值对应的列的值?的主要内容,如果未能解决你的问题,请参考以下文章

查找与另一列的值相关的一个值

在python中,我如何对一列中每个值与另一列中的值发生的次数(多少行)建立矩阵?

如何根据R中小标题中另一列指示的列的值添加列

Pyspark数据帧:根据另一列的值提取列

根据与另一列的部分匹配创建新列

如何计算另一列中特定值的列的平均值?