Repository: dask/dask

Issue:
Dataframe column selection can mix up columns
Currently column selection when reading from CSV (and possibly other IO sources) can mix up column labels, with the wrong name attached to columns. I suspect that this is related to the column projection work that @rjzamora has been doing, but I haven't tracked down the source yet. It also doesn't seem to happen for every CSV.

MWE:

```python
import dask.dataframe as dd
import pandas as pd

URL = "https://github.com/datacamp/python-live-training-template/raw/master/data/airbnb.csv"
dd.read_csv(URL)[["name", "neighbourhood_full"]].head(2)
```
produces 
|    | name                       | neighbourhood_full                                 |
|---:|:---------------------------|:---------------------------------------------------|
|  0 | Brooklyn, Flatlands        | Cozy,budget friendly, cable inc, private entrance! |
|  1 | Manhattan, Upper West Side | Two floor apartment near Central Park              |



```python
import dask.dataframe as dd
import pandas as pd

URL = "https://github.com/datacamp/python-live-training-template/raw/master/data/airbnb.csv"
pd.read_csv(URL)[["name", "neighbourhood_full"]].head(2)
```
produces
|    | name                                               | neighbourhood_full         |
|---:|:---------------------------------------------------|:---------------------------|
|  0 | Cozy,budget friendly, cable inc, private entrance! | Brooklyn, Flatlands        |
|  1 | Two floor apartment near Central Park              | Manhattan, Upper West Side |

- Dask version: current `main`


Discussion:
Unfortunately, seems like it also might be a bit of a heisenbug. I only can reproduce some times, but often enough...
Interesting - Can you say roughly how often the problem shows up? I have tried the repo 100+ times without any issue yet.  **EDIT** - Ah, nevermind. I'm getting it now :)

Resolving patch:
diff --git a/dask/dataframe/io/csv.py b/dask/dataframe/io/csv.py
--- a/dask/dataframe/io/csv.py
+++ b/dask/dataframe/io/csv.py
@@ -68,6 +68,8 @@ def project_columns(self, columns):
         """Return a new CSVFunctionWrapper object with
         a sub-column projection.
         """
+        # Make sure columns is ordered correctly
+        columns = [c for c in self.head.columns if c in columns]
         if columns == self.columns:
             return self
         func = copy.deepcopy(self)


Test patch:
diff --git a/dask/dataframe/io/tests/test_csv.py b/dask/dataframe/io/tests/test_csv.py
--- a/dask/dataframe/io/tests/test_csv.py
+++ b/dask/dataframe/io/tests/test_csv.py
@@ -1652,3 +1652,19 @@ def test_read_csv_groupby_get_group(tmpdir):
     ddfs = ddf1.groupby("foo")
 
     assert_eq(df1, ddfs.get_group(10).compute())
+
+
+def test_csv_getitem_column_order(tmpdir):
+    # See: https://github.com/dask/dask/issues/7759
+
+    path = os.path.join(str(tmpdir), "test.csv")
+    columns = list("abcdefghijklmnopqrstuvwxyz")
+    values = list(range(len(columns)))
+
+    df1 = pd.DataFrame([{c: v for c, v in zip(columns, values)}])
+    df1.to_csv(path)
+
+    # Use disordered and duplicated column selection
+    columns = list("hczzkylaape")
+    df2 = dd.read_csv(path)[columns].head(1)
+    assert_eq(df1[columns], df2)