Repository: modin-project/modin
Pull request: TEST-#5350: port DropDuplicates and LevelAlign benchmarks from pandas github 
<!--
Thank you for your contribution!
Please review the contributing docs: https://modin.readthedocs.io/en/latest/development/contributing.html
if you have questions about contributing.
-->

## What do these changes do?

Adding 2 benchmark classes from pandas benchmark
Source PR https://github.com/modin-project/modin/pull/5047

<!-- Please give a short brief about these changes. -->

- [x] first commit message and PR title follow format outlined [here](https://modin.readthedocs.io/en/latest/development/contributing.html#commit-message-formatting)
  > **_NOTE:_**  If you edit the PR title to match this format, you need to add another commit (even if it's empty) or amend your last commit for the CI job that checks the PR title to pick up the new PR title.
- [x] passes `flake8 modin/ asv_bench/benchmarks scripts/doc_checker.py`
- [x] passes `black --check modin/ asv_bench/benchmarks scripts/doc_checker.py`
- [x] signed commit with `git commit -s` <!-- you can amend your commit with a signature via `git commit -amend -s` -->
- [x] Resolves #5350 <!-- issue must be created for each patch -->
- [x] tests added and passing
- [x] module layout described at `docs/development/architecture.rst` is up-to-date <!-- if you have added, renamed or removed files or directories please update the documentation accordingly -->


Problem statement:
[ASV] port align and DropDuplicates benchmarks from pandas github
Have to add ASV benchmarks related which does the following actions

1)Dataframe.align and Dataframe.reindex

2)drop_duplicates method for Dataframe and Series. 
        - With separate benchmarks for inplace argument true and false 
        - With different types of data such as  string,integer ,nan

Hints from issue discussion:

Commit message: adding ASV benchmarks for drop_duplicates and align methods

Signed-off-by: arunjose696 <arunjose696@gmail.com>

Patch to review:
diff --git a/asv_bench/benchmarks/benchmarks.py b/asv_bench/benchmarks/benchmarks.py
index 10c050251df..8a361b9ecc2 100644
--- a/asv_bench/benchmarks/benchmarks.py
+++ b/asv_bench/benchmarks/benchmarks.py
@@ -21,6 +21,7 @@
 
 import numpy as np
 import pandas._testing as tm
+import math
 
 from .utils import (
     generate_dataframe,
@@ -992,4 +993,96 @@ def time_float_32(self, shape, method):
         execute(self.df_ts_float32.fillna(method=method))
 
 
+class TimeLevelAlign:
+    params = [get_benchmark_shapes("TimeLevelAlign")]
+    param_names = ["shape"]
+
+    def setup(self, shape):
+        row1, col1 = shape[0]
+        row2, col2 = shape[1]
+        Nroot = round(math.sqrt(row1))
+        N = Nroot * Nroot
+        self.index = IMPL.MultiIndex(
+            levels=[np.arange(10), np.arange(Nroot), np.arange(Nroot)],
+            codes=[
+                np.arange(10).repeat(N),
+                np.tile(np.arange(Nroot).repeat(Nroot), 10),
+                np.tile(np.tile(np.arange(Nroot), Nroot), 10),
+            ],
+        )
+        self.df = IMPL.DataFrame(
+            np.random.randn(len(self.index), col1), index=self.index
+        )
+        self.df_level = IMPL.DataFrame(np.random.randn(row2, col2))
+        execute(self.df)
+        execute(self.df_level)
+
+    def time_align_level(self, shape):
+        left, right = self.df.align(self.df_level, level=1, copy=False)
+        execute(left)
+        execute(right)
+
+    def time_reindex_level(self, shape):
+        execute(self.df_level.reindex(self.index, level=1))
+
+
+class TimeDropDuplicates:
+
+    params = [get_benchmark_shapes("TimeDropDuplicates")]
+    param_names = ["shape"]
+
+    def setup(self, shape):
+        N = shape[0]
+        K = shape[1]
+        key1 = tm.makeStringIndex(N).values.repeat(K)
+        key2 = tm.makeStringIndex(N).values.repeat(K)
+        self.df = IMPL.DataFrame(
+            {"key1": key1, "key2": key2, "value": np.random.randn(N * K)}
+        )
+        self.df_nan = self.df.copy()
+        self.df_nan.iloc[:N, :] = np.nan
+        self.s = IMPL.Series(np.random.randint(0, N // 10, size=N))
+        self.s_str = IMPL.Series(np.tile(tm.makeStringIndex(N // 10).values, 10))
+        key1 = np.random.randint(0, K, size=N)
+        self.df_int = IMPL.DataFrame({"key1": key1})
+        execute(self.df), execute(self.df_nan)
+        execute(self.s), execute(self.s_str)
+        execute(self.df_int)
+
+    def time_frame_drop_dups(self, shape):
+        execute(self.df.drop_duplicates(["key1", "key2"]))
+
+    def time_frame_drop_dups_inplace(self, shape):
+        self.df.drop_duplicates(["key1", "key2"], inplace=True)
+        execute(self.df)
+
+    def time_frame_drop_dups_na(self, shape):
+        execute(self.df_nan.drop_duplicates(["key1", "key2"]))
+
+    def time_frame_drop_dups_na_inplace(self, shape):
+        self.df_nan.drop_duplicates(["key1", "key2"], inplace=True)
+        execute(self.df_nan)
+
+    def time_series_drop_dups_int(self, shape):
+        execute(self.s.drop_duplicates())
+
+    def time_series_drop_dups_int_inplace(self, shape):
+        self.s.drop_duplicates(inplace=True)
+        execute(self.s)
+
+    def time_series_drop_dups_string(self, shape):
+        execute(self.s_str.drop_duplicates())
+
+    def time_series_drop_dups_string_inplace(self, shape):
+        self.s_str.drop_duplicates(inplace=True)
+        execute(self.s_str)
+
+    def time_frame_drop_dups_int(self, shape):
+        execute(self.df_int.drop_duplicates())
+
+    def time_frame_drop_dups_int_inplace(self, shape):
+        self.df_int.drop_duplicates(inplace=True)
+        execute(self.df_int)
+
+
 from .utils import setup  # noqa: E402, F401
diff --git a/asv_bench/benchmarks/utils/data_shapes.py b/asv_bench/benchmarks/utils/data_shapes.py
index dd33e5319f8..4b5fa1b3911 100644
--- a/asv_bench/benchmarks/utils/data_shapes.py
+++ b/asv_bench/benchmarks/utils/data_shapes.py
@@ -100,6 +100,7 @@
             "TimeReindex",
             "TimeReindexMethod",
             "TimeFillnaMethodDataframe",
+            "TimeDropDuplicates",
             # IO benchmarks
             "TimeReadCsvSkiprows",
             "TimeReadCsvTrueFalseValues",
@@ -119,6 +120,7 @@
             "TimeConcat",
             "TimeAppend",
             "TimeBinaryOp",
+            "TimeLevelAlign",
         ],
     ),
     (


Code review comments:
diff_hunk: @@ -992,4 +993,96 @@ def time_float_32(self, shape, method):
         execute(self.df_ts_float32.fillna(method=method))
 
 
+class TimeLevelAlign:
+    params = [get_benchmark_shapes("TimeLevelAlign")]
+    param_names = ["shape"]
+
+    def setup(self, shape):
+        row1, col1 = shape[0]
+        row2, col2 = shape[1]
+        Nroot = round(math.sqrt(row1))
+        N = Nroot * Nroot
+        self.index = IMPL.MultiIndex(
+            levels=[np.arange(10), np.arange(Nroot), np.arange(Nroot)],
+            codes=[
+                np.arange(10).repeat(N),
+                np.tile(np.arange(Nroot).repeat(Nroot), 10),
+                np.tile(np.tile(np.arange(Nroot), Nroot), 10),
+            ],
+        )
+        self.df = IMPL.DataFrame(
+            np.random.randn(len(self.index), col1), index=self.index
+        )
+        self.df_level = IMPL.DataFrame(np.random.randn(row2, col2))
+        execute(self.df)
+        execute(self.df_level)
+
+    def time_align_level(self, shape):
+        left, right = self.df.align(self.df_level, level=1, copy=False)
+        execute(left)
+        execute(right)
+
+    def time_reindex_level(self, shape):
+        execute(self.df_level.reindex(self.index, level=1))
+
+
+class TimeDropDuplicates:
path: asv_bench/benchmarks/benchmarks.py
text: @user1:
Let's split it into two classes: `TimeDropDuplicatesDataFrame`, `TimeDropDuplicatesSeries`.

@author:
done

diff_hunk: @@ -992,4 +993,96 @@ def time_float_32(self, shape, method):
         execute(self.df_ts_float32.fillna(method=method))
 
 
+class TimeLevelAlign:
+    params = [get_benchmark_shapes("TimeLevelAlign")]
+    param_names = ["shape"]
+
+    def setup(self, shape):
+        row1, col1 = shape[0]
+        row2, col2 = shape[1]
+        Nroot = round(math.sqrt(row1))
+        N = Nroot * Nroot
+        self.index = IMPL.MultiIndex(
+            levels=[np.arange(10), np.arange(Nroot), np.arange(Nroot)],
+            codes=[
+                np.arange(10).repeat(N),
+                np.tile(np.arange(Nroot).repeat(Nroot), 10),
+                np.tile(np.tile(np.arange(Nroot), Nroot), 10),
+            ],
+        )
+        self.df = IMPL.DataFrame(
+            np.random.randn(len(self.index), col1), index=self.index
+        )
+        self.df_level = IMPL.DataFrame(np.random.randn(row2, col2))
+        execute(self.df)
+        execute(self.df_level)
+
+    def time_align_level(self, shape):
+        left, right = self.df.align(self.df_level, level=1, copy=False)
+        execute(left)
+        execute(right)
+
+    def time_reindex_level(self, shape):
+        execute(self.df_level.reindex(self.index, level=1))
path: asv_bench/benchmarks/benchmarks.py
text: @user1:
```suggestion
        self.df1 = IMPL.DataFrame(
            np.random.randn(len(self.index), col1), index=self.index
        )
        self.df2 = IMPL.DataFrame(np.random.randn(row2, col2))
        execute(self.df1), execute(self.df2)

    def time_align_level(self, shapes):
        left, right = self.df1.align(self.df2, level=1, copy=False)
        execute(left), execute(right)
```

@author:
done

diff_hunk: @@ -992,4 +993,96 @@ def time_float_32(self, shape, method):
         execute(self.df_ts_float32.fillna(method=method))
 
 
+class TimeLevelAlign:
+    params = [get_benchmark_shapes("TimeLevelAlign")]
+    param_names = ["shape"]
+
+    def setup(self, shape):
path: asv_bench/benchmarks/benchmarks.py
text: @user1:
```suggestion
    param_names = ["shapes"]

    def setup(self, shapes):
```

@author:
done