|
1 | 1 | """Sparse Dtype"""
|
2 | 2 |
|
3 | 3 | import re
|
4 |
| -from typing import TYPE_CHECKING, Any, Tuple, Type |
| 4 | +from typing import TYPE_CHECKING, Any, List, Optional, Tuple, Type |
| 5 | +import warnings |
5 | 6 |
|
6 | 7 | import numpy as np
|
7 | 8 |
|
8 |
| -from pandas._typing import Dtype |
| 9 | +from pandas._typing import Dtype, DtypeObj |
| 10 | +from pandas.errors import PerformanceWarning |
9 | 11 |
|
10 | 12 | from pandas.core.dtypes.base import ExtensionDtype
|
11 | 13 | from pandas.core.dtypes.cast import astype_nansafe
|
@@ -352,3 +354,23 @@ def _subtype_with_str(self):
|
352 | 354 | if isinstance(self.fill_value, str):
|
353 | 355 | return type(self.fill_value)
|
354 | 356 | return self.subtype
|
| 357 | + |
| 358 | + def _get_common_dtype(self, dtypes: List[DtypeObj]) -> Optional[DtypeObj]: |
| 359 | + |
| 360 | + fill_values = [x.fill_value for x in dtypes if isinstance(x, SparseDtype)] |
| 361 | + fill_value = fill_values[0] |
| 362 | + |
| 363 | + # np.nan isn't a singleton, so we may end up with multiple |
| 364 | + # NaNs here, so we ignore tha all NA case too. |
| 365 | + if not (len(set(fill_values)) == 1 or isna(fill_values).all()): |
| 366 | + warnings.warn( |
| 367 | + "Concatenating sparse arrays with multiple fill " |
| 368 | + f"values: '{fill_values}'. Picking the first and " |
| 369 | + "converting the rest.", |
| 370 | + PerformanceWarning, |
| 371 | + stacklevel=6, |
| 372 | + ) |
| 373 | + |
| 374 | + # TODO also handle non-numpy other dtypes |
| 375 | + np_dtypes = [x.subtype if isinstance(x, SparseDtype) else x for x in dtypes] |
| 376 | + return SparseDtype(np.find_common_type(np_dtypes, []), fill_value=fill_value) |
0 commit comments