Group Pandas DataFrame重复行,保留最后一个索引



我有一个Pandas DataFrame,其中有一个有意义的索引和各种重复行的组。假设它看起来像这样:

>>> import pandas as pd
>>> df = pd.DataFrame([[1, 1, 1], [2, 3, 4], [2, 3, 4], [1, 1, 1], [1, 1, 1], [1, 1, 1], [3, 3, 3]], columns=["a", "b", "c"])
>>> df
a  b  c
0  1  1  1
1  2  3  4
2  2  3  4
3  1  1  1
4  1  1  1
5  1  1  1
6  3  3  3

我试图删除重复的行(除了每个重复批处理中的第一个),但保留批处理中最后一行的索引。

我正在寻找的结果是这个(即一个新的"last";包含批处理中最后一个重复行的索引的列(如果没有重复,则等于索引):

>>> df2
last  a  b  c
0     0  1  1  1
1     2  2  3  4
3     5  1  1  1
6     6  3  3  3

注意,[1, 1, 1]条目出现了两次,并且被视为单独的块。

我尝试了group_by,duplicated等的各种组合,但没有找到必要的配方。这感觉应该是一件相当标准的事情。是否有一种直接的方法来实现任意数据框架?

编辑:

请注意,我希望保留批处理中第一个项目的原始索引,并为批处理中的最后一个索引添加一个名为last的新列。

在你的例子中

out = df[~df.shift().ne(df).cumsum().duplicated(keep='last')]
Out[19]: 
a  b  c
0  1  1  1
2  2  3  4
5  1  1  1
6  3  3  3

一种方法,类似于BENYs的方法,但使用pandas.DataFrame.diff:

df[~df.diff().cumsum().duplicated(keep='last')]

a  b  c
0  1  1  1
2  2  3  4
5  1  1  1
6  3  3  3

感谢@BENY和@jab的回答,非常接近我所需要的。我添加了额外的last索引列,并进行了一些简单的调整,如下所示:

last_indices = df[~df.diff().cumsum().duplicated(keep='last')].index
df2 = df[~df.diff().cumsum().duplicated(keep='first')]
df2.insert(0, "last", last_indices)

这个收益率:

last  a  b  c
0     0  1  1  1
1     2  2  3  4
3     5  1  1  1
6     6  3  3  3

扩展:

虽然在问题中没有要求,但一个有用的扩展是添加一个包含每个组的计数的列。下面的代码实现了这一点(不依赖于密集的整数索引):

count_groups = df.ne(df.shift()).cumsum().max(axis=1)
counts = count_groups.groupby(count_groups).agg("count")
df2.insert(1, "counts", counts.values)

收益率:

last  counts  a  b  c
0     0       1  1  1  1
1     2       2  2  3  4
3     5       3  1  1  1
6     6       1  3  3  3

相关内容