Skip to content

Commit d97c837

Browse files
committed
Converted pyarrow stringarrays to booleanarray if using logical operators
1 parent b63506e commit d97c837

File tree

1 file changed

+27
-6
lines changed

1 file changed

+27
-6
lines changed

pandas/core/arrays/arrow/array.py

+27-6
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,12 @@
9090
}
9191

9292
ARROW_LOGICAL_FUNCS = {
93-
"and_": pc.and_kleene,
94-
"rand_": lambda x, y: pc.and_kleene(y, x),
95-
"or_": pc.or_kleene,
96-
"ror_": lambda x, y: pc.or_kleene(y, x),
97-
"xor": pc.xor,
98-
"rxor": lambda x, y: pc.xor(y, x),
93+
"and_": lambda x, y: pc.and_kleene(*cast_for_logical(x, y)),
94+
"rand_": lambda x, y: pc.and_kleene(*cast_for_logical(y, x)),
95+
"or_": lambda x, y: pc.or_kleene(*cast_for_logical(x, y)),
96+
"ror_": lambda x, y: pc.or_kleene(*cast_for_logical(y, x)),
97+
"xor": lambda x, y: pc.xor(*cast_for_logical(x, y)),
98+
"rxor": lambda x, y: pc.xor(*cast_for_logical(y, x)),
9999
}
100100

101101
ARROW_BIT_WISE_FUNCS = {
@@ -107,6 +107,20 @@
107107
"rxor": lambda x, y: pc.bit_wise_xor(y, x),
108108
}
109109

110+
def convert_string_to_boolean_array(arr):
111+
if pa.types.is_string(arr.type) or pa.types.is_large_string(arr.type):
112+
string_to_bool = [bool(value.as_py()) for value in arr]
113+
arr = pc.cast(string_to_bool, pa.bool_())
114+
return arr
115+
116+
def cast_for_logical(x, y):
117+
is_x_bool = pa.types.is_boolean(x.type)
118+
is_y_bool = pa.types.is_boolean(y.type)
119+
120+
if (is_x_bool ^ is_y_bool):
121+
return convert_string_to_boolean_array(x), convert_string_to_boolean_array(y)
122+
return x, y
123+
110124
def cast_for_truediv(
111125
arrow_array: pa.ChunkedArray, pa_object: pa.Array | pa.Scalar
112126
) -> tuple[pa.ChunkedArray, pa.Array | pa.Scalar]:
@@ -822,6 +836,13 @@ def _evaluate_op_method(self, other, op, arrow_funcs) -> Self:
822836
result = pc_func(self._pa_array, other)
823837
except pa.ArrowNotImplementedError as err:
824838
raise TypeError(self._op_method_error_message(other_original, op)) from err
839+
840+
if (op.__name__ in ARROW_LOGICAL_FUNCS
841+
and (isinstance(self, pa.lib.BooleanArray) ^
842+
isinstance(other, pa.lib.BooleanArray))
843+
):
844+
return pc.cast(result, pa.bool_())
845+
825846
return type(self)(result)
826847

827848
def _logical_method(self, other, op) -> Self:

0 commit comments

Comments
 (0)