diff --git a/python/cudf/cudf/core/groupby/groupby.py b/python/cudf/cudf/core/groupby/groupby.py index 7cc36aa2565..4d94bb2685e 100644 --- a/python/cudf/cudf/core/groupby/groupby.py +++ b/python/cudf/cudf/core/groupby/groupby.py @@ -1284,6 +1284,27 @@ def _wrap_idxmin_idxmax(self, result: DataFrame | Series, *, skipna: bool): raise ValueError( "Encountered all NA values in a group with skipna=True" ) + # idxmin/idxmax return positional/label indices, which take their + # dtype from the source object's row index — not from the values + # being reduced. Cast the (non-key) result columns accordingly to + # match pandas, where reducing an Int64 column still yields int64 + # indices for a default RangeIndex. Skip the cast when the source + # uses a MultiIndex (no single representative dtype) to avoid + # lossy/unsupported casts. + from cudf.core.multiindex import MultiIndex + + if isinstance(self.obj.index, MultiIndex): + return result + index_dtype = self.obj.index.dtype + key_names = set(self.grouping.names) + if result.ndim == 2: + for name, col in result._column_labels_and_values: + if name in key_names: + continue + if col.dtype != index_dtype: + result._data[name] = col.astype(index_dtype) + elif result.dtype != index_dtype: + result = result.astype(index_dtype) return result def _reduce_numeric_only(self, op: str): diff --git a/python/cudf/cudf/core/indexed_frame.py b/python/cudf/cudf/core/indexed_frame.py index 2df5b20ec45..7fa18b703f8 100644 --- a/python/cudf/cudf/core/indexed_frame.py +++ b/python/cudf/cudf/core/indexed_frame.py @@ -80,6 +80,7 @@ is_column_like, is_mixed_with_object_dtype, is_pandas_nullable_extension_dtype, + is_pandas_nullable_numpy_dtype, ) from cudf.utils.performance_tracking import _performance_tracking from cudf.utils.utils import _warn_no_dask_cudf @@ -6582,56 +6583,322 @@ def convert_dtypes( dtype_backend=None, ) -> Self: """ - Convert columns to the best possible nullable dtypes. + Convert columns from numpy dtypes to the best dtypes that support ``pd.NA``. - If the dtype is numeric, and consists of all integers, convert - to an appropriate integer extension type. Otherwise, convert - to an appropriate floating type. + Parameters + ---------- + infer_objects : bool, default True + Whether object dtypes should be converted to the best possible types. + convert_string : bool, default True + Whether object dtypes should be converted to ``StringDtype()``. + convert_integer : bool, default True + Whether, if possible, conversion can be done to integer extension types. + convert_boolean : bool, defaults True + Whether object dtypes should be converted to ``BooleanDtypes()``. + convert_floating : bool, defaults True + Whether, if possible, conversion can be done to floating extension types. + If `convert_integer` is also True, preference will be give to integer + dtypes if the floats can be faithfully casted to integers. + dtype_backend : {'numpy_nullable', 'pyarrow'}, default 'numpy_nullable' + Back-end data type applied to the resultant :class:`DataFrame` or + :class:`Series` (still experimental). Behaviour is as follows: + + * ``"numpy_nullable"``: returns nullable-dtype-backed + :class:`DataFrame` or :class:`Series`. + * ``"pyarrow"``: returns pyarrow-backed nullable ``ArrowDtype`` + :class:`DataFrame` or :class:`Series`. + + Returns + ------- + Series or DataFrame + Copy of input object with new dtype. + + See Also + -------- + to_datetime : Convert argument to datetime. + to_numeric : Convert argument to a numeric type. + + Notes + ----- + By default, ``convert_dtypes`` will attempt to convert a Series (or each + Series in a DataFrame) to dtypes that support ``pd.NA``. By using the options + ``convert_string``, ``convert_integer``, ``convert_boolean`` and + ``convert_floating``, it is possible to turn off individual conversions + to ``StringDtype``, the integer extension types, ``BooleanDtype`` + or floating extension types, respectively. + + For object-dtyped columns, if ``infer_objects`` is ``True``, use the inference + rules as during normal Series/DataFrame construction. Then, if possible, + convert to ``StringDtype``, ``BooleanDtype`` or an appropriate integer + or floating extension type, otherwise leave as ``object``. + + If the dtype is integer, convert to an appropriate integer extension type. + + If the dtype is numeric, and consists of all integers, convert to an + appropriate integer extension type. Otherwise, convert to an + appropriate floating extension type. + + In the future, as new dtypes are added that support ``pd.NA``, the results + of this method will change to support those new dtypes. + + Examples + -------- + >>> import cudf + >>> import numpy as np + >>> df = cudf.DataFrame( + ... { + ... "a": cudf.Series([1, 2, 3], dtype=np.dtype("int32")), + ... "b": cudf.Series(["x", "y", "z"], dtype=np.dtype("O")), + ... "e": cudf.Series([10, np.nan, 20], dtype=np.dtype("float")), + ... "f": cudf.Series([np.nan, 100.5, 200], dtype=np.dtype("float")), + ... } + ... ) + + Start with a DataFrame with default dtypes. + + >>> df + a b e f + 0 1 x 10.0 NaN + 1 2 y NaN 100.5 + 2 3 z 20.0 200.0 + + >>> df.dtypes + a int32 + b object + e float64 + f float64 + dtype: object + + Convert the DataFrame to use best possible dtypes. + + >>> dfn = df.convert_dtypes() + >>> dfn + a b e f + 0 1 x 10 + 1 2 y 100.5 + 2 3 z 20 200.0 + + >>> dfn.dtypes + a Int32 + b string + e Int64 + f Float64 + dtype: object + + Start with a Series of strings and missing data represented by ``np.nan``. + + >>> s = cudf.Series(["a", "b", np.nan]) + >>> s + 0 a + 1 b + 2 NaN + dtype: str + + Obtain a Series with dtype ``StringDtype``. - All other dtypes are always returned as-is as all dtypes in - cudf are nullable. + >>> s.convert_dtypes() + 0 a + 1 b + 2 + dtype: string """ - if dtype_backend == "pyarrow": - cols = [] - for col in self._columns: - if len(col) == 0 and is_dtype_obj_string(col.dtype): - cols.append(col) - continue - if len(col) != 0 and col.null_count == len(col): - cols.append(as_column(col, dtype=pd.ArrowDtype(pa.null()))) - else: - arrow_dtype = pd.ArrowDtype( - cudf_dtype_to_pa_type(col.dtype) - ) - cols.append(ColumnBase.create(col.plc_column, arrow_dtype)) - return self._from_data_like_self( - self._data._from_columns_like_self(cols, verify=False) + if dtype_backend not in (None, "numpy_nullable", "pyarrow"): + raise ValueError( + f"dtype_backend {dtype_backend} is invalid, only " + "'numpy_nullable' and 'pyarrow' are allowed." ) - if not (convert_floating and convert_integer): - return self.copy() - else: + numpy_to_nullable = { + "int8": pd.Int8Dtype(), + "int16": pd.Int16Dtype(), + "int32": pd.Int32Dtype(), + "int64": pd.Int64Dtype(), + "uint8": pd.UInt8Dtype(), + "uint16": pd.UInt16Dtype(), + "uint32": pd.UInt32Dtype(), + "uint64": pd.UInt64Dtype(), + "float32": pd.Float32Dtype(), + "float64": pd.Float64Dtype(), + } + cols = [] + # Tracks whether each column was "selected" by the convert-* flags + # (used by the ``dtype_backend="pyarrow"`` path below to decide whether + # the column should be converted to ``pd.ArrowDtype``). + converted = [] + for col in self._columns: + dtype = col.dtype + new_col = None + # Map ``pd.ArrowDtype`` inputs to their numpy-nullable equivalents + # only when explicitly asked via ``dtype_backend="numpy_nullable"``. + # Otherwise keep ``pd.ArrowDtype`` columns unchanged (matches pandas). if ( - cudf.get_option("mode.pandas_compatible") - and dtype_backend is None + isinstance(dtype, pd.ArrowDtype) + and dtype_backend == "numpy_nullable" ): - raise NotImplementedError( - "The `dtype_backend` argument is not supported in " - "pandas_compatible mode." + pa_dtype = dtype.pyarrow_dtype + pa_name = str(pa_dtype) + if pa_name in numpy_to_nullable: + eff_dtype = numpy_to_nullable[pa_name] + elif pa.types.is_boolean(pa_dtype): + eff_dtype = pd.BooleanDtype() + elif pa.types.is_string(pa_dtype) or pa.types.is_large_string( + pa_dtype + ): + eff_dtype = pd.StringDtype(na_value=pd.NA) + else: + eff_dtype = dtype + else: + eff_dtype = dtype + + # ``selected`` indicates that the column was actually transformed + # by one of the convert-* flags (used by the pyarrow-backend path + # to decide whether to map to ``pd.ArrowDtype``). + selected = False + if eff_dtype == np.dtype("bool") or isinstance( + eff_dtype, pd.BooleanDtype + ): + if convert_boolean: + selected = True + new_col = col.astype(pd.BooleanDtype(), copy=False) + elif convert_integer: + selected = True + new_col = col.astype(pd.Int64Dtype(), copy=False) + elif convert_floating: + selected = True + new_col = col.astype(pd.Float64Dtype(), copy=False) + elif ( + isinstance(eff_dtype, np.dtype) + and eff_dtype.kind in ("i", "u") + and eff_dtype.name in numpy_to_nullable + ): + if convert_integer: + selected = True + new_col = col.astype( + numpy_to_nullable[eff_dtype.name], copy=False + ) + elif is_pandas_nullable_numpy_dtype( + eff_dtype + ) and eff_dtype.kind in ( + "i", + "u", + ): + if convert_integer: + selected = True + new_col = col.astype(eff_dtype, copy=False) + elif ( + isinstance(eff_dtype, np.dtype) + and eff_dtype.kind == "f" + and eff_dtype.name in numpy_to_nullable + ): + col_filled = col.fillna(0) + as_int = col_filled.astype(np.dtype(np.int64)) + nan_blocks_int = ( + pd.options.future.distinguish_nan_and_na + and col.nan_count > 0 ) - cols = [] - for col in self._columns: - if col.dtype.kind == "f": - col_filled = col.fillna(0) - as_int = col_filled.astype(np.dtype(np.int64)) - if cp.allclose(col_filled, as_int): - cols.append(as_int) - continue - elif isinstance(col.dtype, pd.StringDtype): - col = col.astype(pd.StringDtype(na_value=pd.NA)) - cols.append(col) - return self._from_data_like_self( - self._data._from_columns_like_self(cols, verify=False) + if ( + convert_integer + and not nan_blocks_int + and bool(cp.allclose(col_filled, as_int)) + ): + selected = True + new_col = col.nans_to_nulls().astype( + pd.Int64Dtype(), copy=False + ) + elif convert_floating: + selected = True + new_col = col.astype( + numpy_to_nullable[eff_dtype.name], copy=False + ) + elif ( + is_pandas_nullable_numpy_dtype(eff_dtype) + and eff_dtype.kind == "f" + ): + if convert_floating: + selected = True + new_col = col.astype(eff_dtype, copy=False) + elif isinstance(eff_dtype, pd.StringDtype): + # Empty string columns have no values to infer from; pandas + # leaves the corresponding object column unchanged in that + # case. Match that behavior by skipping conversion. + if convert_string and len(col) > 0: + selected = True + if eff_dtype.na_value is not pd.NA: + new_col = col.astype( + pd.StringDtype(na_value=pd.NA), copy=False + ) + elif eff_dtype == np.dtype("O"): + # Empty object columns have no values to infer from, so + # pandas leaves them as object. Skip conversion to match. + if len(col) == 0: + pass + elif convert_string: + selected = True + new_col = col.astype( + pd.StringDtype(na_value=pd.NA), copy=False + ) + elif infer_objects: + selected = True + new_col = col.astype( + pd.StringDtype(na_value=np.nan), copy=False + ) + was_converted = selected + if new_col is None: + # No conversion applied: still return a copy so that + # modifications to the result don't propagate to ``self`` + # (matches pandas' ``convert_dtypes`` copy semantics). + new_col = col.copy(deep=True) + elif new_col is col: + # ``astype(..., copy=False)`` can return the same column + # when the requested dtype already matches; ensure a copy. + new_col = col.copy(deep=True) + cols.append(new_col) + converted.append(was_converted) + + if dtype_backend == "pyarrow": + # Convert columns that the convert-* flags selected into the + # equivalent ``pd.ArrowDtype``; leave others untouched (matches + # pandas' ``test_pyarrow_backend_no_conversion`` semantics). + # Datetime / timedelta columns aren't matched by any convert-* + # flag, but pandas converts them when *any* flag is enabled. + any_convert = ( + convert_floating + or convert_integer + or convert_boolean + or convert_string ) + arrow_cols = [] + for new_col, was_converted in zip(cols, converted, strict=True): + if not was_converted: + dt = new_col.dtype + is_datetimelike = ( + isinstance(dt, np.dtype) and dt.kind in ("M", "m") + ) or isinstance(dt, pd.DatetimeTZDtype) + if not (any_convert and is_datetimelike): + arrow_cols.append(new_col) + continue + # Empty object columns stay as object (matches pandas' + # ``test_pyarrow_dtype_empty_object``). + if len(new_col) == 0 and is_dtype_obj_string(new_col.dtype): + arrow_cols.append(new_col) + continue + if len(new_col) != 0 and new_col.null_count == len(new_col): + arrow_cols.append( + as_column(new_col, dtype=pd.ArrowDtype(pa.null())) + ) + elif isinstance(new_col.dtype, pd.ArrowDtype): + arrow_cols.append(new_col) + else: + arrow_dtype = pd.ArrowDtype( + cudf_dtype_to_pa_type(new_col.dtype) + ) + arrow_cols.append( + ColumnBase.create(new_col.plc_column, arrow_dtype) + ) + cols = arrow_cols + + return self._from_data_like_self( + self._data._from_columns_like_self(cols, verify=False) + ) @_performance_tracking def pct_change( diff --git a/python/cudf/cudf/pandas/scripts/conftest-patch.py b/python/cudf/cudf/pandas/scripts/conftest-patch.py index 004f4a1c40e..f575d92b552 100644 --- a/python/cudf/cudf/pandas/scripts/conftest-patch.py +++ b/python/cudf/cudf/pandas/scripts/conftest-patch.py @@ -453,8 +453,8 @@ def pytest_unconfigure(config): "tests/copy_view/test_astype.py::test_astype_string_and_object[string[python]-object]": "AssertionError: assert False", "tests/copy_view/test_astype.py::test_astype_string_and_object_update_original[object-string[python]]": "AssertionError: assert False", "tests/copy_view/test_astype.py::test_astype_string_and_object_update_original[string[python]-object]": "AssertionError: assert False", - "tests/copy_view/test_astype.py::test_convert_dtypes": "TODO: Add a reason for failure", - "tests/copy_view/test_astype.py::test_convert_dtypes_infer_objects": "TODO: Add a reason for failure", + "tests/copy_view/test_astype.py::test_convert_dtypes": "cudf does not implement Copy-on-Write, so convert_dtypes always returns a fresh copy and shares_memory is False", + "tests/copy_view/test_astype.py::test_convert_dtypes_infer_objects": "cudf does not implement Copy-on-Write, so convert_dtypes always returns a fresh copy and shares_memory is False", "tests/copy_view/test_chained_assignment_deprecation.py::test_series_setitem[0]": "Failed: DID NOT WARN. No warnings of type (,) were emitted.", "tests/copy_view/test_chained_assignment_deprecation.py::test_series_setitem[indexer1]": "Failed: DID NOT WARN. No warnings of type (,) were emitted.", "tests/copy_view/test_chained_assignment_deprecation.py::test_series_setitem[indexer2]": "Failed: DID NOT WARN. No warnings of type (,) were emitted.", @@ -1428,12 +1428,6 @@ def pytest_unconfigure(config): "tests/extension/test_string.py::TestStringArray::test_astype_own_type[string=string[pyarrow]-True-False]": "TODO: Add a reason for failure", "tests/extension/test_string.py::TestStringArray::test_astype_own_type[string=string[python]-False-False]": "TODO: Add a reason for failure", "tests/extension/test_string.py::TestStringArray::test_astype_own_type[string=string[python]-True-False]": "TODO: Add a reason for failure", - "tests/extension/test_string.py::TestStringArray::test_groupby_agg_extension[string=str[python]-False]": "TODO: Add a reason for failure", - "tests/extension/test_string.py::TestStringArray::test_groupby_agg_extension[string=str[python]-True]": "TODO: Add a reason for failure", - "tests/extension/test_string.py::TestStringArray::test_groupby_agg_extension[string=string[pyarrow]-False]": "TODO: Add a reason for failure", - "tests/extension/test_string.py::TestStringArray::test_groupby_agg_extension[string=string[pyarrow]-True]": "TODO: Add a reason for failure", - "tests/extension/test_string.py::TestStringArray::test_groupby_agg_extension[string=string[python]-False]": "AssertionError: Attributes of DataFrame.iloc[:, 0] (column name='B') are different", - "tests/extension/test_string.py::TestStringArray::test_groupby_agg_extension[string=string[python]-True]": "AssertionError: Attributes of DataFrame.iloc[:, 0] (column name='B') are different", "tests/extension/test_string.py::TestStringArray::test_grouping_grouper[string=str[pyarrow]-False]": "AssertionError: ndarray Expected type , found instead", "tests/extension/test_string.py::TestStringArray::test_grouping_grouper[string=str[pyarrow]-True]": "AssertionError: ndarray Expected type , found instead", "tests/extension/test_string.py::TestStringArray::test_grouping_grouper[string=str[python]-False]": "AssertionError: ndarray Expected type , found instead", @@ -1450,18 +1444,6 @@ def pytest_unconfigure(config): "tests/extension/test_string.py::TestStringArray::test_is_extension_array_dtype[string=string[pyarrow]-True]": "TODO: Add a reason for failure", "tests/extension/test_string.py::TestStringArray::test_is_extension_array_dtype[string=string[python]-False]": "TODO: Add a reason for failure", "tests/extension/test_string.py::TestStringArray::test_is_extension_array_dtype[string=string[python]-True]": "TODO: Add a reason for failure", - "tests/extension/test_string.py::TestStringArray::test_reduce_frame[string=str[python]-False-sum-False]": "AssertionError: Attributes of ExtensionArray are different", - "tests/extension/test_string.py::TestStringArray::test_reduce_frame[string=str[python]-False-sum-True]": "AssertionError: Attributes of ExtensionArray are different", - "tests/extension/test_string.py::TestStringArray::test_reduce_frame[string=str[python]-True-sum-False]": "AssertionError: Attributes of ExtensionArray are different", - "tests/extension/test_string.py::TestStringArray::test_reduce_frame[string=str[python]-True-sum-True]": "AssertionError: Attributes of ExtensionArray are different", - "tests/extension/test_string.py::TestStringArray::test_reduce_frame[string=string[pyarrow]-False-sum-False]": "AssertionError: Attributes of ExtensionArray are different", - "tests/extension/test_string.py::TestStringArray::test_reduce_frame[string=string[pyarrow]-False-sum-True]": "AssertionError: Attributes of ExtensionArray are different", - "tests/extension/test_string.py::TestStringArray::test_reduce_frame[string=string[pyarrow]-True-sum-False]": "AssertionError: Attributes of ExtensionArray are different", - "tests/extension/test_string.py::TestStringArray::test_reduce_frame[string=string[pyarrow]-True-sum-True]": "AssertionError: Attributes of ExtensionArray are different", - "tests/extension/test_string.py::TestStringArray::test_reduce_frame[string=string[python]-False-sum-False]": "AssertionError: Attributes of ExtensionArray are different", - "tests/extension/test_string.py::TestStringArray::test_reduce_frame[string=string[python]-False-sum-True]": "AssertionError: Attributes of ExtensionArray are different", - "tests/extension/test_string.py::TestStringArray::test_reduce_frame[string=string[python]-True-sum-False]": "AssertionError: Attributes of ExtensionArray are different", - "tests/extension/test_string.py::TestStringArray::test_reduce_frame[string=string[python]-True-sum-True]": "AssertionError: Attributes of ExtensionArray are different", "tests/extension/test_string.py::TestStringArray::test_setitem_with_expansion_row[string=str[python]-False]": "AssertionError: Attributes of DataFrame.iloc[:, 0] (column name='data') are different", "tests/extension/test_string.py::TestStringArray::test_setitem_with_expansion_row[string=str[python]-True]": "AssertionError: Attributes of DataFrame.iloc[:, 0] (column name='data') are different", "tests/extension/test_string.py::TestStringArray::test_setitem_with_expansion_row[string=string[python]-False]": "AssertionError: Attributes of DataFrame.iloc[:, 0] (column name='data') are different", @@ -1623,12 +1605,6 @@ def pytest_unconfigure(config): "tests/frame/methods/test_clip.py::TestDataFrameClip::test_dataframe_clip": "TODO: Add a reason for failure", "tests/frame/methods/test_clip.py::TestDataFrameClip::test_inplace_clip": "assert None is A B C D\nfoo_0 0.070575 0.070575 0.070575 0.070575\nfoo_1 ...", "tests/frame/methods/test_combine_first.py::test_combine_first_timestamp_bug[Decimal-scalar11-scalar21]": "AssertionError: DataFrame.iloc[:, 0] (column name='a') are different", - "tests/frame/methods/test_convert_dtypes.py::TestConvertDtypes::test_convert_dtypes[pyarrow-False-expected0]": "TODO: Add a reason for failure", - "tests/frame/methods/test_convert_dtypes.py::TestConvertDtypes::test_convert_dtypes[python-False-expected0]": "TODO: Add a reason for failure", - "tests/frame/methods/test_convert_dtypes.py::TestConvertDtypes::test_convert_dtypes_avoid_block_splitting": "TODO: Add a reason for failure", - "tests/frame/methods/test_convert_dtypes.py::TestConvertDtypes::test_convert_dtypes_pyarrow_to_np_nullable": "TODO: Add a reason for failure", - "tests/frame/methods/test_convert_dtypes.py::TestConvertDtypes::test_pyarrow_backend_no_conversion": "TODO: Add a reason for failure", - "tests/frame/methods/test_convert_dtypes.py::TestConvertDtypes::test_pyarrow_engine_lines_false": "TODO: Add a reason for failure", "tests/frame/methods/test_copy.py::TestCopy::test_copy_consolidates": "TODO: Add a reason for failure", "tests/frame/methods/test_count.py::TestDataFrameCount::test_count": "TODO: Add a reason for failure", "tests/frame/methods/test_cov_corr.py::TestDataFrameCorr::test_corr_numeric_only[False-spearman]": "TODO: Add a reason for failure", @@ -2274,8 +2250,6 @@ def pytest_unconfigure(config): "tests/frame/test_reductions.py::TestDataFrameAnalytics::test_axis_1_empty[var-index1]": "TypeError: Cannot perform reduction 'var' with string dtype", "tests/frame/test_reductions.py::TestDataFrameAnalytics::test_axis_1_empty[var-index2]": "TypeError: Cannot perform reduction 'var' with string dtype", "tests/frame/test_reductions.py::TestDataFrameAnalytics::test_axis_1_empty[var-index3]": "TypeError: Cannot perform reduction 'var' with string dtype", - "tests/frame/test_reductions.py::TestDataFrameAnalytics::test_idxmax_idxmin_convert_dtypes[idxmax-expected_value0]": "TODO: Add a reason for failure", - "tests/frame/test_reductions.py::TestDataFrameAnalytics::test_idxmax_idxmin_convert_dtypes[idxmin-expected_value1]": "TODO: Add a reason for failure", "tests/frame/test_reductions.py::TestDataFrameAnalytics::test_mode_dropna[False-expected3]": "AssertionError: DataFrame.iloc[:, 3] (column name='K') are different", "tests/frame/test_reductions.py::TestDataFrameReductions::test_min_max_dt64_api_consistency_empty_df": "TODO: Add a reason for failure", "tests/frame/test_reductions.py::TestDataFrameReductions::test_min_max_dt64_api_consistency_with_NaT": "TODO: Add a reason for failure", @@ -2452,8 +2426,6 @@ def pytest_unconfigure(config): "tests/groupby/aggregate/test_cython.py::test_cython_agg_EA_known_dtypes[data2-median-always_float-True]": "TODO: Add a reason for failure", "tests/groupby/aggregate/test_cython.py::test_cython_agg_EA_known_dtypes[data2-var-always_float-False]": "TODO: Add a reason for failure", "tests/groupby/aggregate/test_cython.py::test_cython_agg_EA_known_dtypes[data2-var-always_float-True]": "TODO: Add a reason for failure", - "tests/groupby/aggregate/test_cython.py::test_cython_agg_nullable_int[mean]": "TODO: Add a reason for failure", - "tests/groupby/aggregate/test_cython.py::test_cython_agg_nullable_int[median]": "TODO: Add a reason for failure", "tests/groupby/aggregate/test_cython.py::test_cythonized_aggers[prod]": "TODO: Add a reason for failure", "tests/groupby/aggregate/test_cython.py::test_cythonized_aggers[sum]": "TODO: Add a reason for failure", "tests/groupby/aggregate/test_other.py::test_agg_over_numpy_arrays": "TODO: Add a reason for failure", @@ -2741,8 +2713,6 @@ def pytest_unconfigure(config): "tests/groupby/test_categorical.py::test_observed_two_columns[False]": "AssertionError: DataFrame.index level [0] are different", "tests/groupby/test_categorical.py::test_unstack_categorical": "TODO: Add a reason for failure", "tests/groupby/test_counting.py::TestCounting::test_ngroup_distinct": "TODO: Add a reason for failure", - "tests/groupby/test_counting.py::test_count_arrow_string_array[string=string[pyarrow]]": "TODO: Add a reason for failure", - "tests/groupby/test_counting.py::test_count_arrow_string_array[string=string[python]]": "TODO: Add a reason for failure", "tests/groupby/test_cumulative.py::test_cython_api2[False]": "AssertionError: DataFrame are different", "tests/groupby/test_cumulative.py::test_groupby_cumprod_nan_influences_other_columns": "TODO: Add a reason for failure", "tests/groupby/test_cumulative.py::test_numpy_compat[cumprod]": "TODO: Add a reason for failure", @@ -2772,7 +2742,6 @@ def pytest_unconfigure(config): "tests/groupby/test_groupby.py::test_groupby_cumsum_mask[UInt8-True-3]": "TODO: Add a reason for failure", "tests/groupby/test_groupby.py::test_groupby_cumsum_skipna_false": "TODO: Add a reason for failure", "tests/groupby/test_groupby.py::test_groupby_cumsum_timedelta64": "TODO: Add a reason for failure", - "tests/groupby/test_groupby.py::test_groupby_dropna_with_nunique_unique": "AssertionError: Attributes of DataFrame.iloc[:, 0] (column name='('partner', 'nunique')') are different", "tests/groupby/test_groupby.py::test_groupby_dtype_inference_empty": "TODO: Add a reason for failure", "tests/groupby/test_groupby.py::test_groupby_groups_in_BaseGrouper": "TODO: Add a reason for failure", "tests/groupby/test_groupby.py::test_groupby_level_nonmulti": "TODO: Add a reason for failure", @@ -2818,16 +2787,12 @@ def pytest_unconfigure(config): "tests/groupby/test_groupby.py::test_wrap_aggregated_output_multindex": "TODO: Add a reason for failure", "tests/groupby/test_groupby_dropna.py::test_categorical_reducers[idxmax-True-False-False-multi]": "TODO: Add a reason for failure", "tests/groupby/test_groupby_dropna.py::test_categorical_reducers[idxmax-True-False-False-single]": "TODO: Add a reason for failure", - "tests/groupby/test_groupby_dropna.py::test_categorical_reducers[idxmax-True-False-True-single]": "TODO: Add a reason for failure", "tests/groupby/test_groupby_dropna.py::test_categorical_reducers[idxmax-True-True-False-multi]": "TODO: Add a reason for failure", "tests/groupby/test_groupby_dropna.py::test_categorical_reducers[idxmax-True-True-False-single]": "TODO: Add a reason for failure", - "tests/groupby/test_groupby_dropna.py::test_categorical_reducers[idxmax-True-True-True-single]": "TODO: Add a reason for failure", "tests/groupby/test_groupby_dropna.py::test_categorical_reducers[idxmin-True-False-False-multi]": "TODO: Add a reason for failure", "tests/groupby/test_groupby_dropna.py::test_categorical_reducers[idxmin-True-False-False-single]": "TODO: Add a reason for failure", - "tests/groupby/test_groupby_dropna.py::test_categorical_reducers[idxmin-True-False-True-single]": "TODO: Add a reason for failure", "tests/groupby/test_groupby_dropna.py::test_categorical_reducers[idxmin-True-True-False-multi]": "TODO: Add a reason for failure", "tests/groupby/test_groupby_dropna.py::test_categorical_reducers[idxmin-True-True-False-single]": "TODO: Add a reason for failure", - "tests/groupby/test_groupby_dropna.py::test_categorical_reducers[idxmin-True-True-True-single]": "TODO: Add a reason for failure", "tests/groupby/test_groupby_dropna.py::test_categorical_transformers[cumcount-True-False-False]": "TODO: Add a reason for failure", "tests/groupby/test_groupby_dropna.py::test_categorical_transformers[cumcount-True-False-True]": "TODO: Add a reason for failure", "tests/groupby/test_groupby_dropna.py::test_categorical_transformers[cumcount-True-True-False]": "TODO: Add a reason for failure", @@ -2945,7 +2910,6 @@ def pytest_unconfigure(config): "tests/groupby/test_numeric_only.py::TestNumericOnly::test_extrema[min]": "Failed: DID NOT RAISE ", "tests/groupby/test_reductions.py::test_basic_aggregations[float32]": "AssertionError: Attributes of Series are different", "tests/groupby/test_reductions.py::test_basic_aggregations[int32]": "AssertionError: Attributes of Series are different", - "tests/groupby/test_reductions.py::test_empty_categorical[True]": "TODO: Add a reason for failure", "tests/groupby/test_reductions.py::test_first_last_skipna[Float32-False-False-first]": "TODO: Add a reason for failure", "tests/groupby/test_reductions.py::test_first_last_skipna[Float32-False-False-last]": "TODO: Add a reason for failure", "tests/groupby/test_reductions.py::test_first_last_skipna[Float32-True-False-first]": "TODO: Add a reason for failure", @@ -3060,74 +3024,8 @@ def pytest_unconfigure(config): "tests/groupby/test_reductions.py::test_multifunc_skipna[False-min-values28-datetime64[ns]-datetime64[ns]]": "AssertionError: Series are different", "tests/groupby/test_reductions.py::test_multifunc_skipna[False-prod-values0-float64-float64]": "AssertionError: Series are different", "tests/groupby/test_reductions.py::test_multifunc_skipna[True-prod-values3-float64-float64]": "AssertionError: Series are different", - "tests/groupby/test_reductions.py::test_nunique": "TODO: Add a reason for failure", - "tests/groupby/test_reductions.py::test_nunique_with_NaT[key0-data0-True-expected0]": "TODO: Add a reason for failure", "tests/groupby/test_reductions.py::test_nunique_with_NaT[key1-data1-True-expected1]": "TODO: Add a reason for failure", "tests/groupby/test_reductions.py::test_nunique_with_timegrouper": "TODO: Add a reason for failure", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-first-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-first-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-first-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-first-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-last-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-last-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-last-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-last-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-max-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-max-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-max-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-max-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-min-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-min-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-min-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[pyarrow]-min-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-first-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-first-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-first-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-first-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-last-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-last-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-last-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-last-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-max-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-max-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-max-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-max-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-min-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-min-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-min-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=str[python]-min-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-first-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-first-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-first-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-first-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-last-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-last-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-last-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-last-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-max-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-max-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-max-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-max-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-min-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-min-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-min-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[pyarrow]-min-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-first-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-first-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-first-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-first-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-last-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-last-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-last-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-last-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-max-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-max-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-max-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-max-True-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-min-False-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-min-False-False-1]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-min-True-False-0]": "AssertionError: DataFrame are different", - "tests/groupby/test_reductions.py::test_string_dtype_all_na[string=string[python]-min-True-False-1]": "AssertionError: DataFrame are different", "tests/groupby/test_reductions.py::test_sum_skipna[False-values0-float64]": "AssertionError: Series are different", "tests/groupby/test_reductions.py::test_sum_skipna[False-values3-timedelta64[ns]]": "AssertionError: Series are different", "tests/groupby/test_reductions.py::test_sum_skipna_object[False]": "AssertionError: Series are different", @@ -4720,10 +4618,6 @@ def pytest_unconfigure(config): "tests/resample/test_datetime_index.py::test_resample_calendar_day_with_dst[us-2020-10-25-2020-10-27-24h-D-2020-10-26 00:00]": "AssertionError: Series are different", "tests/resample/test_datetime_index.py::test_resample_calendar_day_with_dst[us-2020-10-25-2020-10-27-D-24h-2020-10-26 23:00]": "AssertionError: Series are different", "tests/resample/test_datetime_index.py::test_resample_empty_series_with_tz": "TODO: Add a reason for failure", - "tests/resample/test_datetime_index.py::test_resample_group_info[ms]": "AssertionError: Series.index are different", - "tests/resample/test_datetime_index.py::test_resample_group_info[ns]": "AssertionError: Series.index are different", - "tests/resample/test_datetime_index.py::test_resample_group_info[s]": "AssertionError: Attributes of Series are different", - "tests/resample/test_datetime_index.py::test_resample_group_info[us]": "AssertionError: Series.index are different", "tests/resample/test_datetime_index.py::test_resample_nunique[ms]": "TODO: Add a reason for failure", "tests/resample/test_datetime_index.py::test_resample_nunique[ns]": "TODO: Add a reason for failure", "tests/resample/test_datetime_index.py::test_resample_nunique[s]": "TODO: Add a reason for failure", @@ -5417,163 +5311,6 @@ def pytest_unconfigure(config): "tests/series/methods/test_astype.py::TestAstypeCategorical::test_astype_categorical_to_other": "TODO: Add a reason for failure", "tests/series/methods/test_clip.py::TestSeriesClip::test_clip_against_list_like[upper0-True]": "assert 0 1\n1 2\n2 3\ndtype: int64 is 0 1\n1 2\n2 3\ndtype: int64", "tests/series/methods/test_clip.py::TestSeriesClip::test_clip_against_list_like[upper1-True]": "assert 0 1\n1 2\n2 3\ndtype: int64 is 0 1\n1 2\n2 3\ndtype: int64", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params1-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params1-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params1-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params1-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params1-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params11-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params11-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params11-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params11-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params11-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params12-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params12-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params12-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params12-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params13-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params14-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params14-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params14-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params14-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params15-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params17-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params17-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params17-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params17-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params17-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params19-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params19-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params19-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params19-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params19-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params20-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params20-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params20-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params20-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params21-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params22-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params22-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params22-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params22-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params23-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params25-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params25-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params25-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params25-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params27-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params27-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params27-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params27-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params28-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params28-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params28-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params3-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params3-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params3-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params3-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params3-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params30-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params30-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params30-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params4-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params4-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params4-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params4-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params5-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params6-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params6-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params6-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params6-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params7-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params9-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params9-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params9-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params9-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[False-params9-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params1-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params1-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params1-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params1-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params1-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params1-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params11-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params11-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params11-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params11-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params11-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params11-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params12-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params12-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params12-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params12-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params13-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params14-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params14-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params14-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params14-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params15-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params17-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params17-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params17-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params17-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params17-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params17-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params19-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params19-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params19-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params19-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params19-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params19-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params20-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params20-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params20-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params20-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params21-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params22-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params22-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params22-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params22-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params23-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params25-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params25-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params25-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params25-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params25-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params27-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params27-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params27-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params27-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params27-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params28-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params28-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params28-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params3-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params3-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params3-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params3-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params3-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params3-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params30-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params30-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params30-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params4-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params4-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params4-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params4-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params5-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params6-data12-maindtype12-Float32-expected_other12]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params6-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params6-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params6-data7-maindtype7-Float64-expected_other7]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params7-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params9-data0-maindtype0-Int32-expected_other0]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params9-data1-maindtype1-Int64-expected_other1]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params9-data10-maindtype10-UInt32-expected_other10]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params9-data11-maindtype11-Int8-expected_other11]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params9-data2-maindtype2-expected_default2-expected_other2]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes[True-params9-data6-maindtype6-Int64-expected_other6]": "AssertionError: Attributes of Series are different", - "tests/series/methods/test_convert_dtypes.py::TestSeriesConvertDtypes::test_convert_dtypes_pyarrow_to_np_nullable": "TODO: Add a reason for failure", "tests/series/methods/test_diff.py::TestSeriesDiff::test_diff_bool": "AssertionError: Attributes of Series are different", "tests/series/methods/test_drop.py::test_drop_exception_raised[drop_labels1-0-KeyError-not found in axis]": "Failed: DID NOT RAISE ", "tests/series/methods/test_drop.py::test_drop_unique_and_non_unique_index[data1-index1-drop_labels1-rows-expected_data1-expected_index1]": "TODO: Add a reason for failure", diff --git a/python/cudf/cudf/tests/conftest.py b/python/cudf/cudf/tests/conftest.py index 27d740d7a68..91ecb3247bf 100644 --- a/python/cudf/cudf/tests/conftest.py +++ b/python/cudf/cudf/tests/conftest.py @@ -690,3 +690,33 @@ def pandas_compatible(request): """Param for `pandas_compatible` option""" with cudf.option_context("mode.pandas_compatible", request.param): yield request.param + + +@pytest.fixture(params=[True, False]) +def infer_objects(request): + """Param for `infer_objects` argument""" + return request.param + + +@pytest.fixture(params=[True, False]) +def convert_string(request): + """Param for `convert_string` argument""" + return request.param + + +@pytest.fixture(params=[True, False]) +def convert_integer(request): + """Param for `convert_integer` argument""" + return request.param + + +@pytest.fixture(params=[True, False]) +def convert_boolean(request): + """Param for `convert_boolean` argument""" + return request.param + + +@pytest.fixture(params=[True, False]) +def convert_floating(request): + """Param for `convert_floating` argument""" + return request.param diff --git a/python/cudf/cudf/tests/dataframe/methods/test_convert_dtypes.py b/python/cudf/cudf/tests/dataframe/methods/test_convert_dtypes.py index df4f217c277..7cedf25a25f 100644 --- a/python/cudf/cudf/tests/dataframe/methods/test_convert_dtypes.py +++ b/python/cudf/cudf/tests/dataframe/methods/test_convert_dtypes.py @@ -1,5 +1,6 @@ # SPDX-FileCopyrightText: Copyright (c) 2023-2026, NVIDIA CORPORATION. # SPDX-License-Identifier: Apache-2.0 +import numpy as np import pandas as pd import pytest @@ -7,6 +8,18 @@ from cudf.testing import assert_eq +def _compare_to_pandas(column_specs, kwargs): + gdf = cudf.DataFrame( + {k: cudf.Series(v, dtype=d) for k, (v, d) in column_specs.items()} + ) + pdf = pd.DataFrame( + {k: pd.Series(v, dtype=d) for k, (v, d) in column_specs.items()} + ) + got = gdf.convert_dtypes(**kwargs) + expected = pdf.convert_dtypes(**kwargs) + assert_eq(got, expected, check_dtype=True) + + def test_convert_dtypes(): data = { "a": [1, 2, 3], @@ -47,6 +60,90 @@ def test_convert_dtypes(): gdf[non_nullable_columns].convert_dtypes().to_pandas(nullable=True) +@pytest.mark.parametrize( + "column_specs", + [ + { + "a": ([1, 2, 3], "int32"), + "b": ([1, 2, 3], "int64"), + "c": ([1, 2, 3], "uint16"), + }, + { + "x": ([1.0, 2.0, 3.0], "float64"), + "y": ([1.5, 2.5, 3.5], "float64"), + }, + { + "s": (["a", "b", "c"], "str"), + "o": (["a", "b", "c"], "O"), + }, + { + "i": ([1, 2, 3], "int32"), + "f": ([1.5, 2.5, 3.5], "float64"), + "s": (["a", "b", "c"], "str"), + }, + ], +) +def test_convert_dtypes_dataframe_multi_column(column_specs): + _compare_to_pandas(column_specs, {}) + + +@pytest.mark.parametrize("dtype_backend", ["pyarrow", "numpy_nullable"]) +def test_convert_dtypes_dataframe_backend(dtype_backend): + column_specs = { + "i": ([1, 2, 3], "int64"), + "f": ([1.5, 2.5, 3.5], "float64"), + "s": (["a", "b", "c"], "str"), + } + _compare_to_pandas(column_specs, {"dtype_backend": dtype_backend}) + + +def test_convert_dtypes_dataframe_param_combinations( + infer_objects, + convert_string, + convert_integer, + convert_boolean, + convert_floating, +): + kwargs = { + "infer_objects": infer_objects, + "convert_string": convert_string, + "convert_integer": convert_integer, + "convert_boolean": convert_boolean, + "convert_floating": convert_floating, + } + column_specs = { + "i": ([1, 2, 3], "int32"), + "f_int": ([1.0, 2.0, 3.0], "float64"), + "f_nonint": ([1.5, 2.5, 3.5], "float64"), + "s": (["a", "b", "c"], "str"), + } + _compare_to_pandas(column_specs, kwargs) + + +def test_convert_dtypes_dataframe_returns_copy(): + gdf = cudf.DataFrame( + { + "a": cudf.Series([1, 2, 3], dtype="int64"), + "b": cudf.Series([1.5, 2.5, 3.5], dtype="float64"), + } + ) + original = gdf.copy(deep=True) + result = gdf.convert_dtypes() + result.loc[:, "a"] = pd.NA + result.loc[:, "b"] = pd.NA + assert_eq(gdf, original) + + +def test_convert_dtypes_dataframe_pyarrow_all_null_column(): + _compare_to_pandas( + {"a": ([None, None], "O")}, {"dtype_backend": "pyarrow"} + ) + + +def test_convert_dtypes_dataframe_float_nan_as_null_to_int64(): + _compare_to_pandas({"a": ([10.0, np.nan, 20.0], "float64")}, {}) + + def test_convert_dtypes_pyarrow_null(): pytest.importorskip("pyarrow") data = {"a": [None, None]} diff --git a/python/cudf/cudf/tests/series/methods/test_convert_dtypes.py b/python/cudf/cudf/tests/series/methods/test_convert_dtypes.py index d55a8a56c16..2f900ce5381 100644 --- a/python/cudf/cudf/tests/series/methods/test_convert_dtypes.py +++ b/python/cudf/cudf/tests/series/methods/test_convert_dtypes.py @@ -1,5 +1,6 @@ # SPDX-FileCopyrightText: Copyright (c) 2023-2026, NVIDIA CORPORATION. # SPDX-License-Identifier: Apache-2.0 +import numpy as np import pandas as pd import pytest @@ -7,6 +8,14 @@ from cudf.testing import assert_eq +def _compare_to_pandas(data, dtype, kwargs): + gs = cudf.Series(data, dtype=dtype) + ps = pd.Series(data, dtype=dtype) + got = gs.convert_dtypes(**kwargs) + expected = ps.convert_dtypes(**kwargs) + assert_eq(got, expected, check_dtype=True) + + @pytest.mark.parametrize( "data, dtype", [ @@ -45,6 +54,193 @@ def test_convert_integer_false_convert_floating_true(): assert_eq(result, expected) +def test_convert_dtypes_integer_to_nullable(integer_types_as_str): + _compare_to_pandas([1, 2, 3], integer_types_as_str, {}) + + +def test_convert_dtypes_integer_convert_integer_false(integer_types_as_str): + _compare_to_pandas( + [1, 2, 3], integer_types_as_str, {"convert_integer": False} + ) + + +def test_convert_dtypes_float_noninteger(float_types_as_str): + _compare_to_pandas([1.5, 2.5, 3.5], float_types_as_str, {}) + + +def test_convert_dtypes_float_integer_like_to_int64(float_types_as_str): + _compare_to_pandas([1.0, 2.0, 3.0], float_types_as_str, {}) + + +def test_convert_dtypes_float_convert_integer_false(float_types_as_str): + _compare_to_pandas( + [1.0, 2.0, 3.0], float_types_as_str, {"convert_integer": False} + ) + + +def test_convert_dtypes_float_both_false(float_types_as_str): + _compare_to_pandas( + [1.0, 2.0, 3.0], + float_types_as_str, + {"convert_integer": False, "convert_floating": False}, + ) + + +@pytest.mark.parametrize( + "kwargs", + [ + {}, + {"convert_boolean": False}, + { + "convert_boolean": False, + "convert_integer": False, + "convert_floating": False, + }, + ], +) +def test_convert_dtypes_bool(kwargs): + _compare_to_pandas([True, False, True], "bool", kwargs) + + +@pytest.mark.parametrize( + "kwargs", + [ + {}, + {"convert_string": False, "infer_objects": True}, + {"convert_string": False, "infer_objects": False}, + ], +) +def test_convert_dtypes_object_strings(kwargs): + _compare_to_pandas(["a", "b", "c"], "O", kwargs) + + +@pytest.mark.parametrize( + "kwargs", + [ + {}, + {"convert_string": False}, + {"convert_string": False, "infer_objects": False}, + ], +) +def test_convert_dtypes_string_dtype(kwargs): + _compare_to_pandas(["a", "b", "c"], "str", kwargs) + + +def test_convert_dtypes_already_nullable_unchanged( + all_supported_pandas_nullable_extension_dtypes, +): + scalar, dtype = all_supported_pandas_nullable_extension_dtypes + _compare_to_pandas([scalar, scalar, scalar], dtype, {}) + + +@pytest.mark.parametrize( + "data, dtype", + [ + (["a", "b", "c"], "category"), + (["2001-01-01", "2001-01-02", "2001-01-03"], "datetime64[ns]"), + ], +) +def test_convert_dtypes_non_nullable_kept(data, dtype): + _compare_to_pandas(data, dtype, {}) + + +@pytest.mark.parametrize( + "values, dtype", + [ + ([1, 2, 3], "int64"), + ([1, 2, 3], "int32"), + ([1.0, 2.0, 3.0], "float64"), + ([1.5, 2.5, 3.5], "float64"), + ([True, False, True], "bool"), + (["a", "b", "c"], "str"), + ], +) +def test_convert_dtypes_returns_copy(values, dtype): + gs = cudf.Series(values, dtype=dtype) + original = gs.copy(deep=True) + result = gs.convert_dtypes() + result[result.notna()] = pd.NA + assert_eq(gs, original) + + +@pytest.mark.parametrize( + "data, dtype", + [ + ([1, 2, 3], "int64"), + ([1, 2, 3], "int32"), + ([1.5, 2.5, 3.5], "float64"), + (["a", "b", "c"], "str"), + ], +) +def test_convert_dtypes_pyarrow_backend(data, dtype): + _compare_to_pandas(data, dtype, {"dtype_backend": "pyarrow"}) + + +def test_convert_dtypes_pyarrow_all_null_to_pa_null(): + _compare_to_pandas([None, None], "O", {"dtype_backend": "pyarrow"}) + + +def test_convert_dtypes_float_nan_as_null_converts_to_int(): + _compare_to_pandas([10.0, np.nan, 20.0], "float64", {}) + + +def test_convert_dtypes_float_preserved_nan_blocks_int_conversion(): + with pd.option_context("future.distinguish_nan_and_na", True): + gs = cudf.Series( + [10.0, np.nan, 20.0], dtype="float64", nan_as_null=False + ) + ps = pd.Series([10.0, np.nan, 20.0], dtype="float64") + assert_eq( + gs.convert_dtypes(), + ps.convert_dtypes(), + check_dtype=True, + ) + + +def test_convert_dtypes_float_with_null_to_int64(): + _compare_to_pandas([10.0, None, 20.0], "float64", {}) + + +def test_convert_dtypes_float_nonint_values_with_null(): + _compare_to_pandas([10.5, None, 20.5], "float64", {}) + + +def test_convert_dtypes_pandas_compatible_mode(): + with cudf.option_context("mode.pandas_compatible", True): + _compare_to_pandas([1, 2, 3], "int32", {}) + + +@pytest.mark.parametrize( + "data, dtype", + [ + ([1, 2, 3], "int32"), + ([1, 2, 3], "int64"), + ([1.0, 2.0, 3.0], "float64"), + ([1.5, 2.5, 3.5], "float64"), + ([True, False, True], "bool"), + (["a", "b", "c"], "str"), + (["a", "b", "c"], "O"), + ], +) +def test_convert_dtypes_matches_pandas_all_param_combinations( + data, + dtype, + infer_objects, + convert_string, + convert_integer, + convert_boolean, + convert_floating, +): + kwargs = { + "infer_objects": infer_objects, + "convert_string": convert_string, + "convert_integer": convert_integer, + "convert_boolean": convert_boolean, + "convert_floating": convert_floating, + } + _compare_to_pandas(data, dtype, kwargs) + + def test_convert_dtypes_pyarrow_null(): pytest.importorskip("pyarrow") data = [None, None]