我有一个在列a中具有重复值的数据帧,我想删除重复项,保持列B中值最高的行。

所以这个:

A B
1 10
1 20
2 30
2 40
3 10

应该变成这样:

A B
1 20
2 40
3 10

我猜可能有一种简单的方法可以做到这一点——可能就像在删除重复数据之前对DataFrame进行排序一样简单——但是我不太了解groupby的内部逻辑,无法弄清楚它。有什么建议吗?


当前回答

最上面的答案是做了太多的工作,对于更大的数据集看起来非常慢。应用速度较慢,应尽量避免。Ix已被弃用,也应该避免使用。

df.sort_values('B', ascending=False).drop_duplicates('A').sort_index()

   A   B
1  1  20
3  2  40
4  3  10

或者简单地按所有其他列分组,然后取所需列的最大值。df。groupby (A, as_index = False) .max ()

其他回答

我认为在你的情况下,你真的不需要一组。我会按B列降序排序,然后在A列删除重复项如果你愿意,你也可以有一个新的nice and 像这样干净的索引:

df.sort_values('B', ascending=False).drop_duplicates('A').sort_index().reset_index(drop=True)

我将首先对数据帧进行排序,列B降序,然后删除列A的重复项并保持优先

df = df.sort_values(by='B', ascending=False)
df = df.drop_duplicates(subset='A', keep="first")

没有任何分组

我是通过一个重复问题的链接来到这里的。

对于只有两列,这样做不是更简单吗:

df.groupby('A')['B'].max().reset_index()

并且要保留一整行(当有更多列时,这就是把我带到这里的“重复问题”所问的问题):

df.loc[df.groupby(...)[column].idxmax()]

例如,为了保留'C'取最大值的整行,对于每一组['A', 'B'],我们会这样做:

out = df.loc[df.groupby(['A', 'B')['C'].idxmax()]

当有相对较少的组(即,大量的重复)时,这比drop_duplicate()解决方案(更少的排序)更快:

设置:

n = 1_000_000
df = pd.DataFrame({
    'A': np.random.randint(0, 20, n),
    'B': np.random.randint(0, 20, n),
    'C': np.random.uniform(size=n),
    'D': np.random.choice(list('abcdefghijklmnopqrstuvwxyz'), size=n),
})

(增加sort_index()以确保相等的解):

%timeit df.loc[df.groupby(['A', 'B'])['C'].idxmax()].sort_index()
# 101 ms ± 98.7 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df.sort_values(['C', 'A', 'B'], ascending=False).drop_duplicates(['A', 'B']).sort_index()
# 667 ms ± 784 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

你也可以试试这个

df.drop_duplicates(subset='A', keep='last')

我参考了https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.drop_duplicates.html

这也是可行的:

a=pd.DataFrame({'A':a.groupby('A')['B'].max().index,'B':a.groupby('A')       ['B'].max().values})