Repository: pyjanitor-devs/pyjanitor
Pull request #1100 (2022-05-08 06:07:39)

docstring update
<!-- Thank you for your PR!

BEFORE YOU CONTINUE! Please add the appropriate three-letter abbreviation to your title.

The abbreviations can be:
- [DOC]: Documentation fixes.
- [ENH]: Code contributions and new features.
- [TST]: Test-related contributions.
- [INF]: Infrastructure-related contributions.

Also, do not forget to tag the relevant issue here as well.

Finally, as commits come in, don't forget to regularly rebase!
-->

# PR Description

Please describe the changes proposed in the pull request:

- docstrings cleanup for `fill_direction`, `fill_empty`, `update_where`

**This PR relates to #972 .**

<!-- As you go down the PR template, please feel free to delete sections that are irrelevant. -->

# PR Checklist

<!-- This checklist exists for newcomers who are not yet familiar with our requirements. If you are experienced with
the project, please feel free to delete this section. -->

Please ensure that you have done the following:

1. [ ] PR in from a fork off your branch. Do not PR from `<your_username>`:`dev`, but rather from `<your_username>`:`<feature-branch_name>`.
<!-- Doing this helps us keep the commit history much cleaner than it would otherwise be. -->
2. [ ] If you're not on the contributors list, add yourself to `AUTHORS.md`.
<!-- We'd like to acknowledge your contributions! -->
3. [ ] Add a line to `CHANGELOG.md` under the latest version header (i.e. the one that is "on deck") describing the contribution.
    - Do use some discretion here; if there are multiple PRs that are related, keep them in a single line.

# Automatic checks

There will be automatic checks run on the PR. These include:

- Building a preview of the docs on Netlify
- Automatically linting the code
- Making sure the code is documented
- Making sure that all tests are passed
- Making sure that code coverage doesn't go down.

# Relevant Reviewers

<!-- Finally, please tag relevant maintainers to review. -->

Please tag maintainers to review.

- @ericmjl


ericmjl: <!-- NETLIFY DEPLOY COMMENT GENERATED BY ACTIONS_NETLIFY -->
🚀 Deployed on https://deploy-preview-1100--pyjanitor.netlify.app
samukweku: @ericmjl / @thatlittleboy @pyjanitor-devs/core-devs pls what am I missing regarding the docs build; the preview is not changing to reflect the latest updates
codecov[bot]: # [Codecov](https://codecov.io/gh/pyjanitor-devs/pyjanitor/pull/1100?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pyjanitor-devs) Report
> Merging [#1100](https://codecov.io/gh/pyjanitor-devs/pyjanitor/pull/1100?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pyjanitor-devs) (f49a255) into [dev](https://codecov.io/gh/pyjanitor-devs/pyjanitor/commit/5dfc402efbd5436f4522fff4d1f8667b508b5892?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pyjanitor-devs) (5dfc402) will **decrease** coverage by `54.85%`.
> The diff coverage is `n/a`.

> :exclamation: Current head f49a255 differs from pull request most recent head 4a0ba7e. Consider uploading reports for the commit 4a0ba7e to get more accurate results


```diff
@@             Coverage Diff             @@
##              dev    #1100       +/-   ##
===========================================
- Coverage   97.75%   42.90%   -54.86%     
===========================================
  Files          77       77               
  Lines        3121     3121               
===========================================
- Hits         3051     1339     -1712     
- Misses         70     1782     +1712     
```

thatlittleboy: > @ericmjl / @thatlittleboy @pyjanitor-devs/core-devs pls what am I missing regarding the docs build; the preview is not changing to reflect the latest updates

@samukweku The link for this PR https://deploy-preview-1100--pyjanitor.netlify.app/ contains the latest updates as far as I can see.

![image](https://user-images.githubusercontent.com/30731072/167287921-d17d68d4-3be4-4234-835a-01bfcba192c6.png)

samukweku: thanks @thatlittleboy the issue is from my end then!

Patch:
diff --git a/janitor/functions/fill.py b/janitor/functions/fill.py
index d758d5b..cfd992d 100644
--- a/janitor/functions/fill.py
+++ b/janitor/functions/fill.py
@@ -20,50 +20,36 @@ def fill_direction(df: pd.DataFrame, **kwargs) -> pd.DataFrame:
     and `downup`.
 
 
-    Functional usage syntax:
-
-    ```python
-    import pandas as pd
-    import janitor as jn
-
-    df = pd.DataFrame(...)
-    df = jn.fill_direction(
-                df = df,
-                column_1 = direction_1,
-                column_2 = direction_2,
-            )
-    ```
-
-    Method-chaining usage syntax:
-
-    >>> import pandas as pd
-    >>> import janitor as jn
-    >>> df = pd.DataFrame(
-    ...    {
-    ...        'col1': [1, 2, 3, 4],
-    ...        'col2': [None, 5, 6, 7],
-    ...        'col3': [8, 9, 10, None],
-    ...        'col4': [None, None, 11, None],
-    ...        'col5': [None, 12, 13, None]
-    ...    }
-    ... )
-    >>> df
-       col1  col2  col3  col4  col5
-    0     1   NaN   8.0   NaN   NaN
-    1     2   5.0   9.0   NaN  12.0
-    2     3   6.0  10.0  11.0  13.0
-    3     4   7.0   NaN   NaN   NaN
-    >>> df.fill_direction(
-    ... col2 = 'up',
-    ... col3 = 'down',
-    ... col4 = 'downup',
-    ... col5 = 'updown'
-    ... )
-       col1  col2  col3  col4  col5
-    0     1   5.0   8.0  11.0  12.0
-    1     2   5.0   9.0  11.0  12.0
-    2     3   6.0  10.0  11.0  13.0
-    3     4   7.0  10.0  11.0  13.0
+    Example:
+
+        >>> import pandas as pd
+        >>> import janitor as jn
+        >>> df = pd.DataFrame(
+        ...    {
+        ...        'col1': [1, 2, 3, 4],
+        ...        'col2': [None, 5, 6, 7],
+        ...        'col3': [8, 9, 10, None],
+        ...        'col4': [None, None, 11, None],
+        ...        'col5': [None, 12, 13, None]
+        ...    }
+        ... )
+        >>> df
+           col1  col2  col3  col4  col5
+        0     1   NaN   8.0   NaN   NaN
+        1     2   5.0   9.0   NaN  12.0
+        2     3   6.0  10.0  11.0  13.0
+        3     4   7.0   NaN   NaN   NaN
+        >>> df.fill_direction(
+        ... col2 = 'up',
+        ... col3 = 'down',
+        ... col4 = 'downup',
+        ... col5 = 'updown'
+        ... )
+           col1  col2  col3  col4  col5
+        0     1   5.0   8.0  11.0  12.0
+        1     2   5.0   9.0  11.0  12.0
+        2     3   6.0  10.0  11.0  13.0
+        3     4   7.0  10.0  11.0  13.0
 
     :param df: A pandas DataFrame.
     :param kwargs: Key - value pairs of columns and directions.
@@ -138,39 +124,32 @@ def fill_empty(
 
     This method mutates the original DataFrame.
 
-    Functional usage syntax:
-
-    ```python
-        df = fill_empty(df, column_names=[col1, col2], value=0)
-    ```
-
-    Method chaining syntax:
-
-
-    >>> import pandas as pd
-    >>> import janitor
-    >>> df = pd.DataFrame(
-    ...        {
-    ...            'col1': [1, 2, 3],
-    ...            'col2': [None, 4, None ],
-    ...            'col3': [None, 5, 6]
-    ...        }
-    ...    )
-    >>> df
-       col1  col2  col3
-    0     1   NaN   NaN
-    1     2   4.0   5.0
-    2     3   NaN   6.0
-    >>> df.fill_empty(column_names = 'col2', value = 0)
-       col1  col2  col3
-    0     1   0.0   NaN
-    1     2   4.0   5.0
-    2     3   0.0   6.0
-    >>> df.fill_empty(column_names = ['col2', 'col3'], value = 0)
-       col1  col2  col3
-    0     1   0.0   0.0
-    1     2   4.0   5.0
-    2     3   0.0   6.0
+    Example:
+
+        >>> import pandas as pd
+        >>> import janitor
+        >>> df = pd.DataFrame(
+        ...        {
+        ...            'col1': [1, 2, 3],
+        ...            'col2': [None, 4, None ],
+        ...            'col3': [None, 5, 6]
+        ...        }
+        ...    )
+        >>> df
+           col1  col2  col3
+        0     1   NaN   NaN
+        1     2   4.0   5.0
+        2     3   NaN   6.0
+        >>> df.fill_empty(column_names = 'col2', value = 0)
+           col1  col2  col3
+        0     1   0.0   NaN
+        1     2   4.0   5.0
+        2     3   0.0   6.0
+        >>> df.fill_empty(column_names = ['col2', 'col3'], value = 0)
+           col1  col2  col3
+        0     1   0.0   0.0
+        1     2   4.0   5.0
+        2     3   0.0   6.0
 
 
     :param df: A pandas DataFrame.
diff --git a/janitor/functions/pivot.py b/janitor/functions/pivot.py
index 69a7bee..fb7aaf5 100644
--- a/janitor/functions/pivot.py
+++ b/janitor/functions/pivot.py
@@ -606,6 +606,8 @@ def _computations_pivot_longer(
             name: extract_array(df[name], extract_numpy=True) for name in index
         }
 
+    if len(column_names) != len(set(column_names)):
+        column_names = pd.unique(column_names)
     df = df.loc[:, column_names]
 
     len_index = len(df)
diff --git a/janitor/functions/update_where.py b/janitor/functions/update_where.py
index 6203728..5d960b9 100644
--- a/janitor/functions/update_where.py
+++ b/janitor/functions/update_where.py
@@ -24,38 +24,38 @@ def update_where(
 
     Example usage:
 
-    >>> data = {
-    ...    "a": [1, 2, 3, 4],
-    ...    "b": [5, 6, 7, 8],
-    ...    "c": [0, 0, 0, 0],
-    ... }
-    >>> df = pd.DataFrame(data)
-    >>> df
-       a  b  c
-    0  1  5  0
-    1  2  6  0
-    2  3  7  0
-    3  4  8  0
-    >>> df.update_where(
-    ...    conditions = (df.a > 2) & (df.b < 8),
-    ...    target_column_name = 'c',
-    ...    target_val = 10
-    ... )
-       a  b   c
-    0  1  5   0
-    1  2  6   0
-    2  3  7  10
-    3  4  8   0
-    >>> df.update_where( # supports pandas *query* style string expressions
-    ...    conditions = "a > 2 and b < 8",
-    ...    target_column_name = 'c',
-    ...    target_val = 10
-    ... )
-       a  b   c
-    0  1  5   0
-    1  2  6   0
-    2  3  7  10
-    3  4  8   0
+        >>> data = {
+        ...    "a": [1, 2, 3, 4],
+        ...    "b": [5, 6, 7, 8],
+        ...    "c": [0, 0, 0, 0],
+        ... }
+        >>> df = pd.DataFrame(data)
+        >>> df
+           a  b  c
+        0  1  5  0
+        1  2  6  0
+        2  3  7  0
+        3  4  8  0
+        >>> df.update_where(
+        ...    conditions = (df.a > 2) & (df.b < 8),
+        ...    target_column_name = 'c',
+        ...    target_val = 10
+        ... )
+           a  b   c
+        0  1  5   0
+        1  2  6   0
+        2  3  7  10
+        3  4  8   0
+        >>> df.update_where( # supports pandas *query* style string expressions
+        ...    conditions = "a > 2 and b < 8",
+        ...    target_column_name = 'c',
+        ...    target_val = 10
+        ... )
+           a  b   c
+        0  1  5   0
+        1  2  6   0
+        2  3  7  10
+        3  4  8   0
 
     :param df: The pandas DataFrame object.
     :param conditions: Conditions used to update a target column


Test patch:
diff --git a/tests/functions/test_pivot_longer.py b/tests/functions/test_pivot_longer.py
index a88f6fb..551acf7 100644
--- a/tests/functions/test_pivot_longer.py
+++ b/tests/functions/test_pivot_longer.py
@@ -1156,3 +1156,22 @@ def test_names_transform_numeric():
     ).reset_index()
 
     assert_frame_equal(actual, expected)
+
+
+def test_duplicated_columns():
+    """Test output for duplicated columns."""
+    rows = [["credit", 1, 1, 2, 3]]
+    columns = ["Type", "amount", "active", "amount", "active"]
+
+    df = pd.DataFrame(rows, columns=columns)
+    df = df.set_index("Type")
+
+    actual = pd.DataFrame(
+        {"amount": [1, 2], "active": [1, 3]},
+        index=pd.Index(["credit", "credit"], name="Type"),
+    )
+    expected = df.pivot_longer(
+        names_to=".value", names_pattern="(.+)", ignore_index=False
+    )
+
+    assert_frame_equal(actual, expected)