SimpleImputer converts `int32[pyarrow]` extension array to `float64`, subsequently crashing with numpy `int32` values

### Describe the bug

When using the `SimpleImputer` with a pyarrow-backed pandas DataFrame, any float/integer data is converted to `None`/`float64` instead.
This causes the imputer to be fitted to `float64`, crashing on a dtype assertion when passing it a numpy-backed `int32` DataFrame after fitting.

The flow is the following:
1. The imputer calls `_validate_input`:
  https://github.com/scikit-learn/scikit-learn/blob/675736ae9e3f360975e1f5b477a8eba68a376ba9/sklearn/impute/_base.py#L319
2. This calls `validate_data`:
  https://github.com/scikit-learn/scikit-learn/blob/675736ae9e3f360975e1f5b477a8eba68a376ba9/sklearn/impute/_base.py#L344-L353
3. This calls `check_array`:
  https://github.com/scikit-learn/scikit-learn/blob/675736ae9e3f360975e1f5b477a8eba68a376ba9/sklearn/utils/validation.py#L2951-L2952
4. Our input is a pandas dataframe:
  https://github.com/scikit-learn/scikit-learn/blob/675736ae9e3f360975e1f5b477a8eba68a376ba9/sklearn/utils/validation.py#L909
5. This now checks if the dtypes need to be converted:
  https://github.com/scikit-learn/scikit-learn/blob/675736ae9e3f360975e1f5b477a8eba68a376ba9/sklearn/utils/validation.py#L925-L927
6. Our input is backed by an extension array _and_ `int32[pyarrow]` is an integer datatype, so we return `True` here:
  https://github.com/scikit-learn/scikit-learn/blob/675736ae9e3f360975e1f5b477a8eba68a376ba9/sklearn/utils/validation.py#L714-L724
7. Finally we pass the "needs conversion" check and convert the dataframe to `dtype` (which is `None` here, which apparently means `float64`):
  https://github.com/scikit-learn/scikit-learn/blob/675736ae9e3f360975e1f5b477a8eba68a376ba9/sklearn/utils/validation.py#L966-L971

### Steps/Code to Reproduce

```py
import polars as pl
from sklearn.impute import SimpleImputer
import numpy as np

print(
    SimpleImputer(missing_values=np.nan, strategy='constant', fill_value=0)
      .fit(pl.DataFrame({"a": [10]}, schema={"a": pl.Int32}).to_pandas(use_pyarrow_extension_array=False))
      ._fit_dtype
)
# prints dtype('int32'), as expected

print(
    SimpleImputer(missing_values=np.nan, strategy='constant', fill_value=0)
      .fit(pl.DataFrame({"a": [10]}, schema={"a": pl.Int32}).to_pandas(use_pyarrow_extension_array=True))
      ._fit_dtype
)
# prints dtype('float64') (!!)
```


### Expected Results

Both imputers should be fitted with `int32` values.

### Actual Results

The imputer using the pyarrow extension array is fitted with `float64`.

This causes crashes when using the Imputer with normal `int32` columns backed by numpy, as they won't be converted and therefore the dtypes differ.

### Versions

```shell
System:
    python: 3.12.9 (main, Mar 11 2025, 17:26:57) [Clang 20.1.0 ]
executable: /tmp/scikit/.venv/bin/python3
   machine: Linux-6.14.4-arch1-2-x86_64-with-glibc2.41

Python dependencies:
      sklearn: 1.6.1
          pip: None
   setuptools: None
        numpy: 2.2.5
        scipy: 1.15.3
       Cython: None
       pandas: 2.2.3
   matplotlib: None
       joblib: 1.5.0
threadpoolctl: 3.6.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 16
         prefix: libscipy_openblas
       filepath: /tmp/scikit/.venv/lib/python3.12/site-packages/numpy.libs/libscipy_openblas64_-6bb31eeb.so
        version: 0.3.28
threading_layer: pthreads
   architecture: Haswell

       user_api: blas
   internal_api: openblas
    num_threads: 16
         prefix: libscipy_openblas
       filepath: /tmp/scikit/.venv/lib/python3.12/site-packages/scipy.libs/libscipy_openblas-68440149.so
        version: 0.3.28
threading_layer: pthreads
   architecture: Haswell

       user_api: openmp
   internal_api: openmp
    num_threads: 16
         prefix: libgomp
       filepath: /tmp/scikit/.venv/lib/python3.12/site-packages/scikit_learn.libs/libgomp-a34b3233.so.1.0.0
        version: None
```

COMMENT:
The issue could be the first check in `def _validate_input(self, X, in_fit):`   #

![Image](https://github.com/user-attachments/assets/155ad464-8cd4-48f3-adf6-295888c56cfa)

It is checking for data types and assigning a default from `FLOAT_DTYPES = (np.float64, np.float32, np.float16)`

@gdacciaro will adding support for pyarrow dtypes in the if-else block work?

```
from pandas.api.types import is_extension_array_dtype, is_string_dtype, is_numeric_dtype

if self.strategy in ("most_frequent", "constant"):
        if isinstance(X, list) and any(
            isinstance(elem, str) for row in X for elem in row
        ):
            dtype = object
        else:
            dtype = None
    else:
        # Allow Arrow-backed numeric dtypes
        if hasattr(X, "dtypes") and all(
            is_numeric_dtype(dt) or is_extension_array_dtype(dt)
            for dt in X.dtypes
        ):
            dtype = None  # Let sklearn decide; don't enforce float64
        else:
            dtype = FLOAT_DTYPES

    return dtype
```

Labels: Bug, module:impute