如何在Python pandas Dataframe中识别重复行的第一个出现

10

我有一个Pandas DataFrame,在一组列中存在重复值。例如:

df = pd.DataFrame({'Column1': {0: 1, 1: 2, 2: 3}, 'Column2': {0: 'ABC', 1: 'XYZ', 2: 'ABC'}, 'Column3': {0: 'DEF', 1: 'DEF', 2: 'DEF'}, 'Column4': {0: 10, 1: 40, 2: 10})

In [2]: df
Out[2]: 
   Column1 Column2 Column3  Column4 is_duplicated  dup_index
0        1     ABC     DEF       10         False          0
1        2     XYZ     DEF       40         False          1
2        3     ABC     DEF       10          True          0

第1行和第3行相同。实质上,第3行是第1行的副本。

我正在寻找以下输出:

Is_Duplicate,包含行是否为重复行的信息[可以通过在数据框(Column2, Column3和Column4)列上使用"duplicated"方法来完成]

Dup_Index,重复行的原始索引。

In [3]: df
Out[3]: 
   Column1 Column2 Column3  Column4  Is_Duplicate  Dup_Index
0        1     ABC     DEF       10         False          0
1        2     XYZ     DEF       40         False          1
2        3     ABC     DEF       10          True          0
2个回答

18

有一个DataFrame方法duplicated,可用于第一列:

In [11]: df.duplicated(['Column2', 'Column3', 'Column4'])
Out[11]: 
0    False
1    False
2     True

In [12]: df['is_duplicated'] = df.duplicated(['Column2', 'Column3', 'Column4'])

为了做第二个,您可以尝试像这样:

In [13]: g = df.groupby(['Column2', 'Column3', 'Column4'])

In [14]: df1 = df.set_index(['Column2', 'Column3', 'Column4'])

In [15]: df1.index.map(lambda ind: g.indices[ind][0])
Out[15]: array([0, 1, 0])

In [16]: df['dup_index'] = df1.index.map(lambda ind: g.indices[ind][0])

In [17]: df
Out[17]: 
   Column1 Column2 Column3  Column4 is_duplicated  dup_index
0        1     ABC     DEF       10         False          0
1        2     XYZ     DEF       40         False          1
2        3     ABC     DEF       10          True          0

谢谢,非常优雅的解决方案。 - Rutger Kassies
谢谢你,@AndyHayden。我正在寻找类似于这样的东西来解决我的问题:https://stackoverflow.com/questions/49103097/load-multiple-csv-files-look-for-missing-merchandiseid-in-subsequent-files-cal 。有没有一种方法可以获取最后一次出现并在那里设置列值,而不是将dup_index设置为原始出现?感谢您的帮助。 - Alice
1
谢谢,我明白了。使用 df1.index.map(lambda ind: g.indices[ind][len(g.indices[ind])-1])。 - Alice
@Alice,很高兴你解决了它。抱歉之前没能帮上忙:我确实看了这个问题,但当时无法完全理解/深入挖掘。 - Andy Hayden
感谢@AndyHayden提供的指引。还有一个问题,除了行的最后一次出现之外,是否有任何方法可以将“dup_index”列中的所有条目都置为空或不填充。因此,除了行的最后一次出现之外,没有任何“dup_index”列会有任何值。也已发布为新问题:https://stackoverflow.com/questions/49188701/how-to-identify-and-set-a-column-value-for-only-the-last-occurrence-of-a-duplica - Alice

4

假设您的数据框存储在df中。

您可以使用groupby来获取数据框中非重复行。 在这里,我们需要忽略不属于数据的Column1:

df_nodup = df.groupby(by=['Column2', 'Column3', 'Column4']).first()

您可以使用merge函数将此新数据框与原始数据框合并:
df = df.merge(df_nodup, left_on=['Column2', 'Column3', 'Column4'], right_index=True, suffixes=('', '_dupindex'))

你最终可以使用合并在数据框中的_dupindex列进行简单的数学运算,以添加所需的列:
df['Is_Duplicate'] = df['Column1']!=df['Column1_dupindex']
df['Dup_Index'] = None
df['Dup_Index'] = df['Dup_Index'].where(df['Column1_dupindex']==df['Column1'], df['Column1_dupindex'])
del df['Column1_dupindex']

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