Repository: modin-project/modin

Issue:
Incorrect behavior of `slice_shift` when index has duplicates
### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: all
- **Modin version** (`modin.__version__`): 0.10.1+36.g0a78bef1
- **Python version**: 3.8.10
- **Code we can use to reproduce**:

```python
import ray
import modin.pandas as pd
import pandas
ray.init()

data = [0,1,2,3,]
index = [0,1,2,0,]

pd_df = pandas.DataFrame(data, index=index)
md_df = pd.DataFrame(data, index=index)

print(f'pandas:\n{pd_df.slice_shift()}')
print(f'\nmodin:\n{md_df.slice_shift()}')
```
Output:
```bash
pandas:
   0
1  0
2  1
0  2

modin:
   0
1  1
2  2
```

<!--

Incorrect behavior of `slice_shift` when index has duplicates
### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: all
- **Modin version** (`modin.__version__`): 0.10.1+36.g0a78bef1
- **Python version**: 3.8.10
- **Code we can use to reproduce**:

```python
import ray
import modin.pandas as pd
import pandas
ray.init()

data = [0,1,2,3,]
index = [0,1,2,0,]

pd_df = pandas.DataFrame(data, index=index)
md_df = pd.DataFrame(data, index=index)

print(f'pandas:\n{pd_df.slice_shift()}')
print(f'\nmodin:\n{md_df.slice_shift()}')
```
Output:
```bash
pandas:
   0
1  0
2  1
0  2

modin:
   0
1  1
2  2
```

<!--



Discussion:

Resolving patch:
diff --git a/modin/pandas/dataframe.py b/modin/pandas/dataframe.py
--- a/modin/pandas/dataframe.py
+++ b/modin/pandas/dataframe.py
@@ -1473,27 +1473,21 @@ def slice_shift(self, periods=1, axis=0):  # noqa: PR01, RT01, D200
             if abs(periods) >= len(self.index):
                 return DataFrame(columns=self.columns)
             else:
-                if periods > 0:
-                    new_index = self.index.drop(labels=self.index[:periods])
-                    new_df = self.drop(self.index[-periods:])
-                else:
-                    new_index = self.index.drop(labels=self.index[periods:])
-                    new_df = self.drop(self.index[:-periods])
-
-                new_df.index = new_index
+                new_df = self.iloc[:-periods] if periods > 0 else self.iloc[-periods:]
+                new_df.index = (
+                    self.index[periods:] if periods > 0 else self.index[:periods]
+                )
                 return new_df
         else:
             if abs(periods) >= len(self.columns):
                 return DataFrame(index=self.index)
             else:
-                if periods > 0:
-                    new_columns = self.columns.drop(labels=self.columns[:periods])
-                    new_df = self.drop(self.columns[-periods:], axis="columns")
-                else:
-                    new_columns = self.columns.drop(labels=self.columns[periods:])
-                    new_df = self.drop(self.columns[:-periods], axis="columns")
-
-                new_df.columns = new_columns
+                new_df = (
+                    self.iloc[:, :-periods] if periods > 0 else self.iloc[:, -periods:]
+                )
+                new_df.columns = (
+                    self.columns[periods:] if periods > 0 else self.columns[:periods]
+                )
                 return new_df
 
     def unstack(self, level=-1, fill_value=None):  # noqa: PR01, RT01, D200
diff --git a/modin/pandas/series.py b/modin/pandas/series.py
--- a/modin/pandas/series.py
+++ b/modin/pandas/series.py
@@ -1335,14 +1335,10 @@ def slice_shift(self, periods=1, axis=0):  # noqa: PR01, RT01, D200
             if abs(periods) >= len(self.index):
                 return Series(dtype=self.dtype)
             else:
-                if periods > 0:
-                    new_index = self.index.drop(labels=self.index[:periods])
-                    new_df = self.drop(self.index[-periods:])
-                else:
-                    new_index = self.index.drop(labels=self.index[periods:])
-                    new_df = self.drop(self.index[:-periods])
-
-                new_df.index = new_index
+                new_df = self.iloc[:-periods] if periods > 0 else self.iloc[-periods:]
+                new_df.index = (
+                    self.index[periods:] if periods > 0 else self.index[:periods]
+                )
                 return new_df
         else:
             raise ValueError(


Test patch:
diff --git a/modin/pandas/test/dataframe/test_default.py b/modin/pandas/test/dataframe/test_default.py
--- a/modin/pandas/test/dataframe/test_default.py
+++ b/modin/pandas/test/dataframe/test_default.py
@@ -767,7 +767,7 @@ def test_resample_specific(rule, closed, label, on, level):
 @pytest.mark.parametrize("index", ["default", "ndarray", "has_duplicates"])
 @pytest.mark.parametrize("axis", [0, 1])
 @pytest.mark.parametrize("periods", [0, 1, -1, 10, -10, 1000000000, -1000000000])
-def test_shift(data, index, axis, periods):
+def test_shift_slice_shift(data, index, axis, periods):
     modin_df, pandas_df = create_test_dfs(data)
     if index == "ndarray":
         data_column_length = len(data[next(iter(data))])
@@ -783,22 +783,6 @@ def test_shift(data, index, axis, periods):
         modin_df.shift(periods=periods, axis=axis, fill_value=777),
         pandas_df.shift(periods=periods, axis=axis, fill_value=777),
     )
-
-
-@pytest.mark.parametrize("data", test_data_values, ids=test_data_keys)
-@pytest.mark.parametrize("index", ["default", "ndarray"])
-@pytest.mark.parametrize("axis", [0, 1])
-@pytest.mark.parametrize("periods", [0, 1, -1, 10, -10, 1000000000, -1000000000])
-def test_slice_shift(data, index, axis, periods):
-    if index == "default":
-        modin_df = pd.DataFrame(data)
-        pandas_df = pandas.DataFrame(data)
-    elif index == "ndarray":
-        data_column_length = len(data[next(iter(data))])
-        index_data = np.arange(2, data_column_length + 2)
-        modin_df = pd.DataFrame(data, index=index_data)
-        pandas_df = pandas.DataFrame(data, index=index_data)
-
     df_equals(
         modin_df.slice_shift(periods=periods, axis=axis),
         pandas_df.slice_shift(periods=periods, axis=axis),
diff --git a/modin/pandas/test/test_series.py b/modin/pandas/test/test_series.py
--- a/modin/pandas/test/test_series.py
+++ b/modin/pandas/test/test_series.py
@@ -2916,16 +2916,6 @@ def test_shape(data):
     assert modin_series.shape == pandas_series.shape
 
 
-@pytest.mark.parametrize("data", test_data_values, ids=test_data_keys)
-def test_shift(data):
-    modin_series, pandas_series = create_test_series(data)
-    df_equals(modin_series.shift(), pandas_series.shift())
-    df_equals(modin_series.shift(fill_value=777), pandas_series.shift(fill_value=777))
-    df_equals(modin_series.shift(periods=7), pandas_series.shift(periods=7))
-    df_equals(modin_series.shift(periods=-3), pandas_series.shift(periods=-3))
-    eval_general(modin_series, pandas_series, lambda df: df.shift(axis=1))
-
-
 @pytest.mark.parametrize("data", test_data_values, ids=test_data_keys)
 def test_size(data):
     modin_series, pandas_series = create_test_series(data)
@@ -2942,18 +2932,29 @@ def test_skew(data, skipna):
 
 
 @pytest.mark.parametrize("data", test_data_values, ids=test_data_keys)
-@pytest.mark.parametrize("index", ["default", "ndarray"])
+@pytest.mark.parametrize("index", ["default", "ndarray", "has_duplicates"])
 @pytest.mark.parametrize("periods", [0, 1, -1, 10, -10, 1000000000, -1000000000])
-def test_slice_shift(data, index, periods):
-    if index == "default":
-        modin_series, pandas_series = create_test_series(data)
-    elif index == "ndarray":
-        modin_series, pandas_series = create_test_series(data)
+def test_shift_slice_shift(data, index, periods):
+    modin_series, pandas_series = create_test_series(data)
+    if index == "ndarray":
         data_column_length = len(data[next(iter(data))])
-        index_data = np.arange(2, data_column_length + 2)
-        modin_series.index = index_data
-        pandas_series.index = index_data
+        modin_series.index = pandas_series.index = np.arange(2, data_column_length + 2)
+    elif index == "has_duplicates":
+        modin_series.index = pandas_series.index = list(modin_series.index[:-3]) + [
+            0,
+            1,
+            2,
+        ]
 
+    df_equals(
+        modin_series.shift(periods=periods),
+        pandas_series.shift(periods=periods),
+    )
+    df_equals(
+        modin_series.shift(periods=periods, fill_value=777),
+        pandas_series.shift(periods=periods, fill_value=777),
+    )
+    eval_general(modin_series, pandas_series, lambda df: df.shift(axis=1))
     df_equals(
         modin_series.slice_shift(periods=periods),
         pandas_series.slice_shift(periods=periods),