Repository: modin-project/modin

Issue:
read_csv bug


### System information
- **OS Platform and Distribution (e.g., Linux Ubuntu 16.04)**: CentOS 7.4.1708
- **Modin installed from (source or binary)**: binary
- **Modin version**: 0.6.3
- **Python version**: 3.7.4
- **Exact command to reproduce**: 

```
import modin.pandas as pd

data = pd.read_csv(baf, skiprows=10, names = ['CHR', 'POS', 'REF_COUNT', 'ALT_COUNT', 'BAF'], dtype = {'CHR' : str}, sep='\t')

data.head()
    CHR    POS  REF_COUNT  ALT_COUNT                  BAF
0   CHR    POS  REF_COUNT  ALT_COUNT                  BAF
1  chrFAKE  FAKE1         FAKE          FAKE               0
2  chrFAKE  FAKE2         FAKE         FAKE   0
3  chrFAKE  FAKE3         FAKE         FAKE  0
```

### Describe the problem
I'm exploring modin now and I have a question. When I load a CSV file using skiprows modin does not skip the rows. Is this expected and if so should it come with a warning? This was described as a bug (that only occurs when names is used) on the google group.

### Source code / logs




Discussion:
Thanks for the report @JenniferShelton!

This is indeed a bug, and only happens when `names` and `skiprows` are set together. I will make sure this gets in the next release.

Here is a temporary workaround so you are not blocked on the next release:

```python
import modin.pandas as pd

names = ['CHR', 'POS', 'REF_COUNT', 'ALT_COUNT', 'BAF']
data = pd.read_table(baf, skiprows=10, header=None)
data.columns = names
data.head()
```
Let me know if this helps in the sort term. Thanks again for the report!

Resolving patch:
diff --git a/modin/engines/base/io/text/csv_reader.py b/modin/engines/base/io/text/csv_reader.py
--- a/modin/engines/base/io/text/csv_reader.py
+++ b/modin/engines/base/io/text/csv_reader.py
@@ -3,59 +3,10 @@
 from pandas.io.parsers import _validate_usecols_arg
 import pandas
 import py
-import os
 import sys
 
 
 class CSVReader(TextFileReader):
-    @classmethod
-    def _skip_header(
-        cls,
-        f,
-        comment=None,
-        skiprows=None,
-        encoding=None,
-        header="infer",
-        names=None,
-        **kwargs
-    ):
-        lines_read = 0
-        if header is None:
-            return lines_read
-        elif header == "infer":
-            if names is not None:
-                return lines_read
-            else:
-                header = 0
-        # Skip lines before the header
-        if isinstance(skiprows, int):
-            lines_read += skiprows
-            for _ in range(skiprows):
-                f.readline()
-            skiprows = None
-
-        header_lines = header + 1 if isinstance(header, int) else max(header) + 1
-        header_lines_skipped = 0
-        # Python 2 files use a read-ahead buffer which breaks our use of tell()
-        for line in iter(f.readline, ""):
-            lines_read += 1
-            skip = False
-            if not skip and comment is not None:
-                if encoding is not None:
-                    skip |= line.decode(encoding)[0] == comment
-                else:
-                    skip |= line.decode()[0] == comment
-            if not skip and callable(skiprows):
-                skip |= skiprows(lines_read)
-            elif not skip and hasattr(skiprows, "__contains__"):
-                skip |= lines_read in skiprows
-
-            if not skip:
-                header_lines_skipped += 1
-                if header_lines_skipped == header_lines:
-                    return lines_read
-        return lines_read
-
     @classmethod
     def read(cls, filepath_or_buffer, **kwargs):
         if isinstance(filepath_or_buffer, str):
@@ -142,14 +93,22 @@ def read(cls, filepath_or_buffer, **kwargs):
             usecols=usecols,
         )
         with cls.file_open(filepath_or_buffer, "rb", compression_type) as f:
-            if kwargs.get("encoding", None) is not None:
-                partition_kwargs["skiprows"] = 1
-                f.seek(0, os.SEEK_SET)  # Return to beginning of file
-
             # Skip the header since we already have the header information and skip the
             # rows we are told to skip.
-            kwargs["skiprows"] = skiprows
-            cls._skip_header(f, **kwargs)
+            if isinstance(skiprows, int) or skiprows is None:
+                if skiprows is None:
+                    skiprows = 0
+                header = kwargs.get("header", "infer")
+                if header == "infer" and kwargs.get("names", None) is None:
+                    skiprows += 1
+                elif isinstance(header, int):
+                    skiprows += header + 1
+                elif hasattr(header, "__iter__") and not isinstance(header, str):
+                    skiprows += max(header) + 1
+                for _ in range(skiprows):
+                    f.readline()
+            if kwargs.get("encoding", None) is not None:
+                partition_kwargs["skiprows"] = 1
             # Launch tasks to read partitions
             partition_ids = []
             index_ids = []
@@ -197,6 +156,11 @@ def read(cls, filepath_or_buffer, **kwargs):
         if index_col is None:
             row_lengths = cls.materialize(index_ids)
             new_index = pandas.RangeIndex(sum(row_lengths))
+            # pandas has a really weird edge case here.
+            if kwargs.get("names", None) is not None and skiprows > 1:
+                new_index = pandas.RangeIndex(
+                    skiprows - 1, new_index.stop + skiprows - 1
+                )
         else:
             index_objs = cls.materialize(index_ids)
             row_lengths = [len(o) for o in index_objs]


Test patch:
diff --git a/modin/pandas/test/test_io.py b/modin/pandas/test/test_io.py
--- a/modin/pandas/test/test_io.py
+++ b/modin/pandas/test/test_io.py
@@ -905,8 +905,23 @@ def test_from_csv_skiprows(make_csv_file):
 
     pandas_df = pandas.read_csv(TEST_CSV_FILENAME, skiprows=2)
     modin_df = pd.read_csv(TEST_CSV_FILENAME, skiprows=2)
+    df_equals(modin_df, pandas_df)
 
-    assert modin_df_equals_pandas(modin_df, pandas_df)
+    pandas_df = pandas.read_csv(
+        TEST_CSV_FILENAME, names=["c1", "c2", "c3", "c4"], skiprows=2
+    )
+    modin_df = pd.read_csv(
+        TEST_CSV_FILENAME, names=["c1", "c2", "c3", "c4"], skiprows=2
+    )
+    df_equals(modin_df, pandas_df)
+
+    pandas_df = pandas.read_csv(
+        TEST_CSV_FILENAME, names=["c1", "c2", "c3", "c4"], skiprows=lambda x: x % 2
+    )
+    modin_df = pd.read_csv(
+        TEST_CSV_FILENAME, names=["c1", "c2", "c3", "c4"], skiprows=lambda x: x % 2
+    )
+    df_equals(modin_df, pandas_df)
 
 
 def test_from_csv_encoding(make_csv_file):