假设我有一个数据框
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)。
答案 0 :(得分:1)
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
排序只能对现有列进行排序,因此我们需要创建绝对值列(使用.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
答案 1 :(得分:0)
您可以使用绝对值创建其他列,然后使用最小值创建loc
df['absValues'] = df.column1.abs()
df.loc[df['absValues'] == df.groupby('Category')['absValues'].transform('min')]
.drop_duplicates(['Category']).drop('absValues', 1)
out
Category Data1 column1
1 A 'SOMEDATA' 2
4 B 'SOMEDATA' 1
这样,您将为DataFrame中的每一行保留所有其他列。
如果需要在每个组中返回所有等于min的值,请从代码中删除.drop_duplicates()
。
答案 2 :(得分:0)
这是一种计算效率更高的解决方案。
TL; DR版本
df.loc[df.groupby('Category')['column1'].idxmin()]