prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Bool values get flipped when converting Arrow table to DataFrame
  Using the latest version:
  `vaex==2.6.1`
  
  Just realised that when converting an Arrow table to a DataFrame, bool columns get flipped and converted to integers:
  
  ```python
  import vaex
  from pyarrow import feather
  
  bool_array = [False, True, True, False]
  pdf = pd.DataFrame({"col1": bool_array})
  pdf.to_feather("test_data.feather")
  arrow_table = feather.read_table("test_data.feather")
  vaex.from_arrow_table(arrow_table)
  ```
  
  ```
  #  | col1
  -- | --
  0  | 1
  1  | 0
  2  | 0
  3  | 1
  ```
  
  </issue>
  <code>
  [start of packages/vaex-arrow/vaex_arrow/convert.py]
  1 """Convert between arrow and vaex/numpy columns/arrays without doing memory copies."""
  2 import pyarrow
  3 import numpy as np
  4 from vaex.column import ColumnStringArrow
  5 
  6 def arrow_array_from_numpy_array(array):
  7     dtype = array.dtype
  8     mask = None
  9     if np.ma.isMaskedArray(array):
  10         mask = array.mask
  11         # arrow 0.16 behaves weird in this case https://github.com/vaexio/vaex/pull/639
  12         if mask is np.False_:
  13             mask = None
  14         elif mask is np.True_:
  15             raise ValueError('not sure what pyarrow does with mask=True')
  16         array = array.data
  17     if dtype.kind == 'S':
  18         type = pyarrow.binary(dtype.itemsize)
  19         arrow_array = pyarrow.array(array, type, mask=mask)
  20     else:
  21         if not dtype.isnative:
  22             array = array.astype(dtype.newbyteorder('='))
  23         arrow_array = pyarrow.Array.from_pandas(array, mask=mask)
  24     return arrow_array
  25 
  26 from vaex.dataframe import Column
  27 
  28 
  29 def column_from_arrow_array(arrow_array):
  30     arrow_type = arrow_array.type
  31     buffers = arrow_array.buffers()
  32     if len(buffers) == 2:
  33         return numpy_array_from_arrow_array(arrow_array)
  34     elif len(buffers) == 3 and  isinstance(arrow_array.type, type(pyarrow.string())):
  35         bitmap_buffer, offsets, string_bytes = arrow_array.buffers()
  36         if arrow_array.null_count == 0:
  37             null_bitmap = None  # we drop any null_bitmap when there are no null counts
  38         else:
  39             null_bitmap = np.frombuffer(bitmap_buffer, 'uint8', len(bitmap_buffer))
  40         offsets = np.frombuffer(offsets, np.int32, len(offsets)//4)
  41         if string_bytes is None:
  42             string_bytes = np.array([], dtype='S1')
  43         else:
  44             string_bytes = np.frombuffer(string_bytes, 'S1', len(string_bytes))
  45         column = ColumnStringArrow(offsets, string_bytes, len(arrow_array), null_bitmap=null_bitmap)
  46         return column
  47     else:
  48         raise TypeError('type unsupported: %r' % arrow_type)
  49 
  50 
  51 def numpy_array_from_arrow_array(arrow_array):
  52     arrow_type = arrow_array.type
  53     buffers = arrow_array.buffers()
  54     assert len(buffers) == 2
  55     bitmap_buffer, data_buffer = buffers
  56     if isinstance(arrow_type, type(pyarrow.binary(1))):  # todo, is there a better way to typecheck?
  57         # mimics python/pyarrow/array.pxi::Array::to_numpy
  58         assert len(buffers) == 2
  59         dtype = "S" + str(arrow_type.byte_width)
  60         # arrow seems to do padding, check if it is all ok
  61         expected_length = arrow_type.byte_width * len(arrow_array)
  62         actual_length = len(buffers[-1])
  63         if actual_length < expected_length:
  64             raise ValueError('buffer is smaller (%d) than expected (%d)' % (actual_length, expected_length))
  65         array = np.frombuffer(buffers[-1], dtype, len(arrow_array))# TODO: deal with offset ? [arrow_array.offset:arrow_array.offset + len(arrow_array)]
  66     else:
  67         dtype = arrow_array.type.to_pandas_dtype()
  68     if np.bool_ == dtype:
  69         # TODO: this will also be a copy, we probably want to support bitmasks as well
  70         bitmap = np.frombuffer(data_buffer, np.uint8, len(data_buffer))
  71         array = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))
  72     else:
  73         array = np.frombuffer(data_buffer, dtype, len(arrow_array))
  74 
  75     if bitmap_buffer is not None:
  76         bitmap = np.frombuffer(bitmap_buffer, np.uint8, len(bitmap_buffer))
  77         mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))
  78         array = np.ma.MaskedArray(array, mask=mask)
  79     return array
  80 
  81 def numpy_mask_from_arrow_mask(bitmap, length):
  82     # arrow uses a bitmap https://github.com/apache/arrow/blob/master/format/Layout.md
  83     # we do have to change the ordering of the bits
  84     return 1-np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length]
  85 
  86 
  87 
  88 def arrow_table_from_vaex_df(ds, column_names=None, selection=None, strings=True, virtual=False):
  89     """Implementation of Dataset.to_arrow_table"""
  90     names = []
  91     arrays = []
  92     for name, array in ds.to_items(column_names=column_names, selection=selection, strings=strings, virtual=virtual):
  93         names.append(name)
  94         arrays.append(arrow_array_from_numpy_array(array))
  95     return pyarrow.Table.from_arrays(arrays, names)
  96 
  97 def vaex_df_from_arrow_table(table):
  98     from .dataset import DatasetArrow
  99     return DatasetArrow(table=table)
  100
  [end of packages/vaex-arrow/vaex_arrow/convert.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/packages/vaex-arrow/vaex_arrow/convert.py b/packages/vaex-arrow/vaex_arrow/convert.py
  --- a/packages/vaex-arrow/vaex_arrow/convert.py
  +++ b/packages/vaex-arrow/vaex_arrow/convert.py
  @@ -53,6 +53,7 @@
       buffers = arrow_array.buffers()
       assert len(buffers) == 2
       bitmap_buffer, data_buffer = buffers
  +    offset = arrow_array.offset
       if isinstance(arrow_type, type(pyarrow.binary(1))):  # todo, is there a better way to typecheck?
           # mimics python/pyarrow/array.pxi::Array::to_numpy
           assert len(buffers) == 2
  @@ -68,13 +69,13 @@
       if np.bool_ == dtype:
           # TODO: this will also be a copy, we probably want to support bitmasks as well
           bitmap = np.frombuffer(data_buffer, np.uint8, len(data_buffer))
  -        array = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))
  +        array = numpy_bool_from_arrow_bitmap(bitmap, len(arrow_array) + offset)[offset:]
       else:
  -        array = np.frombuffer(data_buffer, dtype, len(arrow_array))
  +        array = np.frombuffer(data_buffer, dtype, len(arrow_array) + offset)[offset:]
   
       if bitmap_buffer is not None:
           bitmap = np.frombuffer(bitmap_buffer, np.uint8, len(bitmap_buffer))
  -        mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))
  +        mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array) + offset)[offset:]
           array = np.ma.MaskedArray(array, mask=mask)
       return array
   
  @@ -83,7 +84,10 @@
       # we do have to change the ordering of the bits
       return 1-np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length]
   
  -
  +def numpy_bool_from_arrow_bitmap(bitmap, length):
  +    # arrow uses a bitmap https://github.com/apache/arrow/blob/master/format/Layout.md
  +    # we do have to change the ordering of the bits
  +    return np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length].view(np.bool_)
   
   def arrow_table_from_vaex_df(ds, column_names=None, selection=None, strings=True, virtual=False):
       """Implementation of Dataset.to_arrow_table"""
  
verification_info: {"golden_diff": "diff --git a/packages/vaex-arrow/vaex_arrow/convert.py b/packages/vaex-arrow/vaex_arrow/convert.py\n--- a/packages/vaex-arrow/vaex_arrow/convert.py\n+++ b/packages/vaex-arrow/vaex_arrow/convert.py\n@@ -53,6 +53,7 @@\n     buffers = arrow_array.buffers()\n     assert len(buffers) == 2\n     bitmap_buffer, data_buffer = buffers\n+    offset = arrow_array.offset\n     if isinstance(arrow_type, type(pyarrow.binary(1))):  # todo, is there a better way to typecheck?\n         # mimics python/pyarrow/array.pxi::Array::to_numpy\n         assert len(buffers) == 2\n@@ -68,13 +69,13 @@\n     if np.bool_ == dtype:\n         # TODO: this will also be a copy, we probably want to support bitmasks as well\n         bitmap = np.frombuffer(data_buffer, np.uint8, len(data_buffer))\n-        array = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))\n+        array = numpy_bool_from_arrow_bitmap(bitmap, len(arrow_array) + offset)[offset:]\n     else:\n-        array = np.frombuffer(data_buffer, dtype, len(arrow_array))\n+        array = np.frombuffer(data_buffer, dtype, len(arrow_array) + offset)[offset:]\n \n     if bitmap_buffer is not None:\n         bitmap = np.frombuffer(bitmap_buffer, np.uint8, len(bitmap_buffer))\n-        mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))\n+        mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array) + offset)[offset:]\n         array = np.ma.MaskedArray(array, mask=mask)\n     return array\n \n@@ -83,7 +84,10 @@\n     # we do have to change the ordering of the bits\n     return 1-np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length]\n \n-\n+def numpy_bool_from_arrow_bitmap(bitmap, length):\n+    # arrow uses a bitmap https://github.com/apache/arrow/blob/master/format/Layout.md\n+    # we do have to change the ordering of the bits\n+    return np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length].view(np.bool_)\n \n def arrow_table_from_vaex_df(ds, column_names=None, selection=None, strings=True, virtual=False):\n     \"\"\"Implementation of Dataset.to_arrow_table\"\"\"\n", "issue": "Bool values get flipped when converting Arrow table to DataFrame\nUsing the latest version:\r\n`vaex==2.6.1`\r\n\r\nJust realised that when converting an Arrow table to a DataFrame, bool columns get flipped and converted to integers:\r\n\r\n```python\r\nimport vaex\r\nfrom pyarrow import feather\r\n\r\nbool_array = [False, True, True, False]\r\npdf = pd.DataFrame({\"col1\": bool_array})\r\npdf.to_feather(\"test_data.feather\")\r\narrow_table = feather.read_table(\"test_data.feather\")\r\nvaex.from_arrow_table(arrow_table)\r\n```\r\n\r\n```\r\n#  | col1\r\n-- | --\r\n0  | 1\r\n1  | 0\r\n2  | 0\r\n3  | 1\r\n```\n", "before_files": [{"content": "\"\"\"Convert between arrow and vaex/numpy columns/arrays without doing memory copies.\"\"\"\nimport pyarrow\nimport numpy as np\nfrom vaex.column import ColumnStringArrow\n\ndef arrow_array_from_numpy_array(array):\n    dtype = array.dtype\n    mask = None\n    if np.ma.isMaskedArray(array):\n        mask = array.mask\n        # arrow 0.16 behaves weird in this case https://github.com/vaexio/vaex/pull/639\n        if mask is np.False_:\n            mask = None\n        elif mask is np.True_:\n            raise ValueError('not sure what pyarrow does with mask=True')\n        array = array.data\n    if dtype.kind == 'S':\n        type = pyarrow.binary(dtype.itemsize)\n        arrow_array = pyarrow.array(array, type, mask=mask)\n    else:\n        if not dtype.isnative:\n            array = array.astype(dtype.newbyteorder('='))\n        arrow_array = pyarrow.Array.from_pandas(array, mask=mask)\n    return arrow_array\n\nfrom vaex.dataframe import Column\n\n\ndef column_from_arrow_array(arrow_array):\n    arrow_type = arrow_array.type\n    buffers = arrow_array.buffers()\n    if len(buffers) == 2:\n        return numpy_array_from_arrow_array(arrow_array)\n    elif len(buffers) == 3 and  isinstance(arrow_array.type, type(pyarrow.string())):\n        bitmap_buffer, offsets, string_bytes = arrow_array.buffers()\n        if arrow_array.null_count == 0:\n            null_bitmap = None  # we drop any null_bitmap when there are no null counts\n        else:\n            null_bitmap = np.frombuffer(bitmap_buffer, 'uint8', len(bitmap_buffer))\n        offsets = np.frombuffer(offsets, np.int32, len(offsets)//4)\n        if string_bytes is None:\n            string_bytes = np.array([], dtype='S1')\n        else:\n            string_bytes = np.frombuffer(string_bytes, 'S1', len(string_bytes))\n        column = ColumnStringArrow(offsets, string_bytes, len(arrow_array), null_bitmap=null_bitmap)\n        return column\n    else:\n        raise TypeError('type unsupported: %r' % arrow_type)\n\n\ndef numpy_array_from_arrow_array(arrow_array):\n    arrow_type = arrow_array.type\n    buffers = arrow_array.buffers()\n    assert len(buffers) == 2\n    bitmap_buffer, data_buffer = buffers\n    if isinstance(arrow_type, type(pyarrow.binary(1))):  # todo, is there a better way to typecheck?\n        # mimics python/pyarrow/array.pxi::Array::to_numpy\n        assert len(buffers) == 2\n        dtype = \"S\" + str(arrow_type.byte_width)\n        # arrow seems to do padding, check if it is all ok\n        expected_length = arrow_type.byte_width * len(arrow_array)\n        actual_length = len(buffers[-1])\n        if actual_length < expected_length:\n            raise ValueError('buffer is smaller (%d) than expected (%d)' % (actual_length, expected_length))\n        array = np.frombuffer(buffers[-1], dtype, len(arrow_array))# TODO: deal with offset ? [arrow_array.offset:arrow_array.offset + len(arrow_array)]\n    else:\n        dtype = arrow_array.type.to_pandas_dtype()\n    if np.bool_ == dtype:\n        # TODO: this will also be a copy, we probably want to support bitmasks as well\n        bitmap = np.frombuffer(data_buffer, np.uint8, len(data_buffer))\n        array = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))\n    else:\n        array = np.frombuffer(data_buffer, dtype, len(arrow_array))\n\n    if bitmap_buffer is not None:\n        bitmap = np.frombuffer(bitmap_buffer, np.uint8, len(bitmap_buffer))\n        mask = numpy_mask_from_arrow_mask(bitmap, len(arrow_array))\n        array = np.ma.MaskedArray(array, mask=mask)\n    return array\n\ndef numpy_mask_from_arrow_mask(bitmap, length):\n    # arrow uses a bitmap https://github.com/apache/arrow/blob/master/format/Layout.md\n    # we do have to change the ordering of the bits\n    return 1-np.unpackbits(bitmap).reshape((len(bitmap),8))[:,::-1].reshape(-1)[:length]\n\n\n\ndef arrow_table_from_vaex_df(ds, column_names=None, selection=None, strings=True, virtual=False):\n    \"\"\"Implementation of Dataset.to_arrow_table\"\"\"\n    names = []\n    arrays = []\n    for name, array in ds.to_items(column_names=column_names, selection=selection, strings=strings, virtual=virtual):\n        names.append(name)\n        arrays.append(arrow_array_from_numpy_array(array))\n    return pyarrow.Table.from_arrays(arrays, names)\n\ndef vaex_df_from_arrow_table(table):\n    from .dataset import DatasetArrow\n    return DatasetArrow(table=table)\n", "path": "packages/vaex-arrow/vaex_arrow/convert.py"}]}