Repository: pyjanitor-devs/pyjanitor

Issue:
New Function Proposal: drop_duplicated_column
Function to drop duplicated columns and retain a column based on its order.

Example:

```
In [1]: import pandas as pd; import janitor
In [2]: df = pd.DataFrame({"a": range(10), "b": range(10), "A": range(10)})                                                                                                                                
In [3]: df.clean_names()                                                                                                                                                                                   
Out[15]: 
   a  b  a
0  0  0  0
1  1  1  1
2  2  2  2
3  3  3  3
4  4  4  4
5  5  5  5
6  6  6  6
7  7  7  7
8  8  8  8
9  9  9  9

# remove duplicate columns, remove a column, given its name and its order
In [4]: df.clean_names().drop_duplicated_column(column_name="a", column_order=0)                                                                                                                                                    
Out[16]: 
   b  a
0  0  0
In [17]:                       
In [17]:                                                                                                                                                                                                    ```                                                                                                                                                                             ```
1  1  1
2  2  2
3  3  3
4  4  4
5  5  5
6  6  6
7  7  7
8  8  8
9  9  9                                                                                                                                                                                            ```





Discussion:
@ricky-lim if you'd like to go ahead and work on this, please do so!
yes, I'd like to work on this for today's sprint

Resolving patch:
diff --git a/janitor/functions.py b/janitor/functions.py
--- a/janitor/functions.py
+++ b/janitor/functions.py
@@ -2723,3 +2723,56 @@ def groupby_agg(
     df = df.merge(df_grp, on=by)
 
     return df
+
+
+@pf.register_dataframe_method
+def drop_duplicate_columns(
+    df: pd.DataFrame, column_name: str, nth_index: int = 0
+) -> pd.DataFrame:
+    """
+    Removes a duplicated column specified by column_name, its index
+
+    Column order 0 is to remove the first column,
+           order 1 is to remove the second column, and etc
+
+    The corresponding tidyverse R's library is:
+    `select(-<column_name>_<nth_index + 1>)`
+
+    Method chaining example:
+
+    .. code-block:: python
+
+        df = pd.DataFrame({
+            "a": range(10),
+            "b": range(10),
+            "A": range(10, 20),
+            "a*": range(20, 30),
+        }).clean_names(remove_special=True)
+
+        # remove a duplicated second 'a' column
+        df.drop_duplicate_columns(column_name="a", nth_index=1)
+
+
+
+    :param df: A pandas DataFrame
+    :param column_name: Column to be removed
+    :param nth_index: Among the duplicated columns,
+      select the nth column to drop.
+    :return: A pandas DataFrame
+    """
+    cols = df.columns.to_list()
+    col_indexes = [
+        col_idx
+        for col_idx, col_name in enumerate(cols)
+        if col_name == column_name
+    ]
+
+    # given that a column could be duplicated,
+    # user could opt based on its order
+    removed_col_idx = col_indexes[nth_index]
+    # get the column indexes without column that is being removed
+    filtered_cols = [
+        c_i for c_i, c_v in enumerate(cols) if c_i != removed_col_idx
+    ]
+
+    return df.iloc[:, filtered_cols]


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -118,6 +118,20 @@ def chemdf():
     return df
 
 
+@pytest.fixture
+def df_duplicated_columns():
+    data = {
+        "a": range(10),
+        "b": range(10),
+        "A": range(10, 20),
+        "a*": range(20, 30),
+    }
+    df = pd.DataFrame(data)
+    # containing three 'a' columns being duplicated
+    clean_df = df.clean_names(remove_special=True)
+    return clean_df
+
+
 def pytest_configure():
     pytest.TEST_DATA_DIR = TEST_DATA_DIR
     pytest.EXAMPLES_DIR = EXAMPLES_DIR
diff --git a/tests/functions/test_drop_duplicate_columns.py b/tests/functions/test_drop_duplicate_columns.py
new file mode 100644
--- /dev/null
+++ b/tests/functions/test_drop_duplicate_columns.py
@@ -0,0 +1,52 @@
+import pandas as pd
+import pytest
+from pandas.testing import assert_frame_equal
+
+import janitor
+
+
+@pytest.mark.functions
+def test_drop_duplicate_columns(df_duplicated_columns):
+    # df_duplicated_columns contains columns 'a', duplicated three times
+    clean_df = df_duplicated_columns.drop_duplicate_columns(column_name="a")
+    assert clean_df.columns.to_list() == ["b", "a", "a"]
+    expected_df = pd.DataFrame(
+        {"b": range(10), "a": range(10, 20), "a*": range(20, 30)}
+    ).clean_names(remove_special=True)
+    assert_frame_equal(clean_df, expected_df)
+
+
+@pytest.mark.functions
+def test_drop_duplicate_columns_for_second_duplicated_column(
+    df_duplicated_columns
+):
+    clean_df = df_duplicated_columns.drop_duplicate_columns(
+        column_name="a", nth_index=1
+    )
+    expected_df = pd.DataFrame(
+        {"a": range(10), "b": range(10), "a*": range(20, 30)}
+    ).clean_names(remove_special=True)
+    assert clean_df.columns.to_list() == ["a", "b", "a"]
+    assert_frame_equal(clean_df, expected_df)
+
+
+@pytest.mark.functions
+def test_drop_duplicate_columns_for_third_duplicated_column(
+    df_duplicated_columns
+):
+    clean_df = df_duplicated_columns.drop_duplicate_columns(
+        column_name="a", nth_index=2
+    )
+    expected_df = pd.DataFrame(
+        {"a": range(10), "b": range(10), "A": range(10, 20)}
+    ).clean_names(remove_special=True)
+    assert clean_df.columns.to_list() == ["a", "b", "a"]
+    assert_frame_equal(clean_df, expected_df)
+
+
+@pytest.mark.functions
+def test_drop_duplicate_columns_with_error(df_duplicated_columns):
+    with pytest.raises(IndexError):
+        df_duplicated_columns.drop_duplicate_columns(
+            column_name="a", nth_index=3
+        )