Pandas not removing duplicates

Viewed 127

In the following script

import pandas as pd

def start():
    df_dict = {"A": [1,2,3,3,4], "B": [1,2,2,3,4]}
    df = pd.DataFrame(df_dict)

    df.drop_duplicates(inplace = True, keep = "last")

    print(df)

if __name__ == "__main__":
    start()

The duplicates in df are not removed. What could be the reason

Current output:

   A  B
0  1  1
1  2  2
2  3  2
3  3  3
4  4  4

Expected output:

   A  B
0  1  1
1  2  2
3  3  3
4  4  4
3 Answers

The .drop_duplicates() method looks at duplicate rows for all columns of the dataframe, so you need to use .drop_duplicates() while subsetting for each of the two columns, then get the intersection of these two subset dataframes (inner merge). Instead of printing out the resulting dataframe, it's probably more in your interest to have your function return the dataframe.

import pandas as pd

def start():
    df_dict = {"A": [1,2,3,3,4], "B": [1,2,2,3,4]}
    df = pd.DataFrame(df_dict)

    # drop duplicates within each column
    df1 = df.drop_duplicates(subset='A', keep='last')
    df2 = df.drop_duplicates(subset='B', keep='last')

    return pd.merge(df1,df2,how='inner')

if __name__ == "__main__":
    result = start() 

Output:

>>> result
   A  B
0  1  1
1  3  3
2  4  4

The issue is df.drop_duplicates() looks at the whole row not just one column. Given your current data frame there are no unique rows.

So say you want to drop rows based off of duplicates in a single column. The main issue now is how do you determine which row to drop.

The example below will only keep the first occurrence of a value in a row based off of the 'A' column and it does not reset the dataframe index.

import pandas as pd

def start():
    df_dict = {"A": [1,2,3,3,4], "B": [1,2,2,3,4]}
    df = pd.DataFrame(df_dict)

    df_copy = df
    unique_list = []
    for index, value in df_copy.iterrows():

      if value['A'] not in unique_list:
        unique_list.append(value['A'])
      else:
        df = df.drop(index) 
    
    return df

start()

Output:


    A   B
0   1   1
1   2   2
2   3   2
4   4   4

Thanks to Derek O. I reached a modified version of his answer without the merge statement

import pandas as pd

def start():
    df_dict = {"A": [1,2,3,3,4], "B": [1,2,2,3,4]}
    df = pd.DataFrame(df_dict)

    df = df.drop_duplicates(subset = ["A"], keep = "last").drop_duplicates(subset = ["B"], keep = "last")

    print(df)

if __name__ == "__main__":
    start()

Which produces the expected result of the question

Related