Repository: modin-project/modin

Issue:
Series __getitem__ does not accept bool indexer or slice
<!--
General questions should be asked on the mailing list modin-dev@googlegroups.com.

Before submitting an issue, please fill out the following form.
-->

### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: OSX
- **Modin installed from (source or binary)**: source
- **Modin version**: source
- **Python version**: 3.6
- **Exact command to reproduce**: `df["col1"][:30]` and `df["col1"][df["col1"] == "Value"]`

<!--
You can obtain the Modin version with

python -c "import modin; print(modin.__version__)"
-->

### Describe the problem
The `__getitem__` logic in `Series` is not complete. It is missing the bool indexer case and it also throws an error on slices.
<!-- Describe the problem clearly here. -->

### Source code / logs
```python
import modin.pandas as pd
s = pd.Series(list(range(1000))
s[:30]
s[s > 500]
```
<!-- Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached. Try to provide a reproducible test case that is the bare minimum necessary to generate the problem. -->



Discussion:

Resolving patch:
diff --git a/modin/pandas/series.py b/modin/pandas/series.py
--- a/modin/pandas/series.py
+++ b/modin/pandas/series.py
@@ -4,6 +4,7 @@
 
 import numpy as np
 import pandas
+from pandas.core.common import is_bool_indexer
 from pandas.core.dtypes.common import is_dict_like, is_list_like, is_scalar
 import sys
 import warnings
@@ -154,14 +155,25 @@ def __floordiv__(self, right):
         return self.floordiv(right)
 
     def __getitem__(self, key):
-        if (
-            key in self.keys()
-            or is_list_like(key)
-            and all(k in self.keys() for k in key)
-        ):
-            return self.loc[key]
+        if isinstance(key, Series) and key.dtype == np.bool:
+            # This ends up being significantly faster than looping through and getting
+            # each item individually.
+            key = key._to_pandas()
+        if is_bool_indexer(key):
+            return self.loc[self.index[key]]
         else:
-            return self.iloc[key]
+            # The check for whether or not `key` is in `keys()` will throw a TypeError
+            # if the object is not hashable. When that happens, we just use the `iloc`.
+            try:
+                if (
+                    is_list_like(key)
+                    and all(k in self.keys() for k in key)
+                    or key in self.keys()
+                ):
+                    return self.loc[key]
+            except TypeError:
+                pass
+        return self.iloc[key]
 
     def __int__(self):
         return int(self.squeeze())


Test patch:
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
@@ -273,6 +273,10 @@ def test___getitem__(data):
     df_equals(
         modin_series[modin_series.index[-1]], pandas_series[pandas_series.index[-1]]
     )
+    modin_series = pd.Series(list(range(1000)))
+    pandas_series = pandas.Series(list(range(1000)))
+    df_equals(modin_series[:30], pandas_series[:30])
+    df_equals(modin_series[modin_series > 500], pandas_series[pandas_series > 500])
 
 
 @pytest.mark.parametrize("data", test_data_values, ids=test_data_keys)