按分组后获取最小值 - Pandas

3
我有一个如下格式的表格:
data = {'City' : ['London', 'Paris', 'Paris','NY' 'London'], 'Distance' : [5, 1, 7, 2, 6]}
df = pd.DataFrame(data)
df

    City    Distance
0   London  5
1   Paris   1
2   Paris   7
3   NY      2
4   London  6

我想创建一个表格,所有行都具有唯一的“城市”值,当存在两个或更多具有相同“城市”值的行时,希望返回具有最低“距离”的行。因此,在这种情况下,我希望得到这样的表格:
City    Distance
London  5
Paris   1
NY      2

我知道我可以使用:

df.groupby('City')

但我不知道应该添加什么来返回最小的“距离”。

祝好, 罗莎


2
只需要 idxmin ;) - jezrael
你需要使用 df.loc[df.groupby('City')['Distance'].idxmin()] - jezrael
我找不到完全重复的答案,所以创建一个答案... - jezrael
@jezrael 给你:https://dev59.com/wmAg5IYBdhLWcg3wm7_7 - miradulo
我重新打开了,所以不能将其关闭为重复项... - jezrael
在使用groupby和min()时保留其他列 - miradulo
5个回答

9
您需要使用DataFrameGroupBy.idxmin来获取每个组中最小Distance的索引,然后通过loc选择行:
df1 = df.loc[df.groupby('City', sort=False)['Distance'].idxmin()]
print (df1)
     City  Distance
0  London         5
1   Paris         1
3      NY         2

详情:

print (df.groupby('City', sort=False)['Distance'].idxmin())
City
London    0
Paris     1
NY        3
Name: Distance, dtype: int64

我有一个类似的问题,但我想找到不等于0的最小值,并且有两列而不是一列。 - Geosphere
@Geosphere - 不确定是否理解,您能否创建一个新的问题,附上示例数据、期望输出以及您尝试过的内容? - jezrael
是的。我有一个数据框中有3列:x,y,time。我想要检索的是具有最小时间但时间应大于0的行,因为在这种情况下x,y具有相同的值。 - Geosphere
@Geosphere - 是的,请尝试创建一个新的 :) - jezrael
https://stackoverflow.com/questions/49469300/pandas-dataframe-find-the-row-with-minimum-value-based-on-two-columns-but-grea - Geosphere
显示剩余4条评论

5

有时候 groupby 是不必要的,可以尝试使用 drop_duplicates

df.sort_values('Distance').drop_duplicates('City')

Out[377]: 
     City  Distance
0  London         5
1   Paris         1
3      NY         2

1
我认为这种方法应该很快。而且,在排序中不必包括“'City'”。如果你把它省略掉,就不需要其他的sort_index了。df.sort_values('City').drop_duplicates('City') - piRSquared
1
我喜欢你的解决方案。这让我想起了我们曾经进行的这个讨论 :D 链接 - IanS

1
你可以使用


>>> df.groupby(['City'], sort=False)['Distance'].min()
City
London    5
Paris     1
NY        2
Name: Distance, dtype: int64

3
很遗憾,这并不能解决OP中表达的问题。问题明确要求返回每个分组所在行的最小值。这将始终返回一个序列,其索引为唯一城市名称,对应着最小距离。任何其他列都将丢失。 - piRSquared

1

我的观点是,@jezrael在groupby中提供了最惯用的方法。我曾在其他答案中提供过同样的解决方案。但是,这里还有其他一些选择。

选项1
apply内使用pd.DataFrame.nsmallest
即使api有点笨拙,这也提供了清晰的逻辑。我认为这个版本的nsmallest应该可用于groupby对象。但是,在pandas 0.20.3中,它没有。因此,我们在通用的apply方法中使用它。确保在调用groupby时使用group_keys=False,以避免额外的索引。

df.groupby('City', group_keys=False).apply(
    lambda d: d.nsmallest(1, columns='Distance'))

     City  Distance
0  London         5
3      NY         2
1   Paris         1

选项2被@Wen选择了,所以我已经删除。

0

这是一个老问题,但为了完整起见:

df.sort_values(by=['Distance'], ascending=True).groupby('City').first().reset_index(drop=False)

提供相同的输出。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接