【问题标题】:pandas groupby and then select a row by value of column (min,max, for example)pandas groupby,然后按列的值选择一行(例如,最小值,最大值)
【发布时间】:2019-03-15 15:47:52
【问题描述】:

假设我有一个数据框

Category Data1 column1
A 'SOMEDATA' 10
A 'SOMEDATA' 2
A 'SOMEDATA' -10
B 'SOMEDATA' 10
B 'SOMEDATA' 1
B 'SOMEDATA' -10

等等

我想按列值在每组中选择一行。例如,ABS(column1)

所以结果数据是

Category Data1 column1
A 'SOMEDATA' 2
B 'SOMEDATA'  1

如何在 python 中做到这一点?

我不知道如何返回整行。例如,

df.groupby('Category')['column1'].min();

这只会返回 'Category' min(column1)。

【问题讨论】:

标签: python pandas aggregate


【解决方案1】:

这是一个计算效率更高的解决方案。

TL;DR 版本

df.loc[df.groupby('Category')['column1'].idxmin()]

【讨论】:

  • 优雅美丽!谢谢
【解决方案2】:

sort 然后.drop_duplicates,如果您想要基于绝对值的单个最小行。

(df.assign(to_sort = df.column1.abs()).sort_values('to_sort')
     .drop_duplicates('Category').drop(columns='to_sort'))

  Category       Data1  column1
4        B  'SOMEDATA'        1
1        A  'SOMEDATA'        2

Sort 只能对现有列进行排序,因此我们需要创建绝对值列(使用.assign)。然后排序确保最小绝对值首先出现,删除重复项保留每个类别的第一行,现在是最小绝对值行。

也可以使用groupby,如果您需要每组返回多于一行,这会更好:

df.assign(to_sort = df.column1.abs()).sort_values('to_sort').groupby(df.Category).head(1)

或者,您可以使用groupby 的结果进行切片。这在您想要返回与最小值匹配的 所有 行的情况下很有用:

df[df.groupby(df.Category, group_keys=False).apply(lambda x: x.column1 == x.column1.abs().min())]

  Category       Data1  column1
1        A  'SOMEDATA'        2
4        B  'SOMEDATA'        1

【讨论】:

    猜你喜欢
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    相关资源
    最近更新 更多