|
5 | 5 |
|
6 | 6 | import numpy as np
|
7 | 7 |
|
| 8 | +from pandas._config import using_string_dtype |
| 9 | + |
8 | 10 | from pandas._libs import lib
|
9 | 11 | from pandas.compat._optional import import_optional_dependency
|
10 | 12 | from pandas.errors import (
|
|
13 | 15 | )
|
14 | 16 | from pandas.util._exceptions import find_stack_level
|
15 | 17 |
|
16 |
| -from pandas.core.dtypes.common import pandas_dtype |
| 18 | +from pandas.core.dtypes.common import ( |
| 19 | + is_string_dtype, |
| 20 | + pandas_dtype, |
| 21 | +) |
17 | 22 | from pandas.core.dtypes.dtypes import (
|
18 | 23 | BaseMaskedDtype,
|
19 | 24 | )
|
@@ -326,13 +331,29 @@ def read(self) -> DataFrame:
|
326 | 331 | ser = frame[key]
|
327 | 332 | if isinstance(ser.dtype, BaseMaskedDtype):
|
328 | 333 | new_dtype[key] = ser.dtype.numpy_dtype
|
| 334 | + if ( |
| 335 | + key in old_dtype |
| 336 | + and not using_string_dtype() |
| 337 | + and is_string_dtype(old_dtype[key]) |
| 338 | + and not isinstance(old_dtype[key], StringDtype) |
| 339 | + and ser.array._hasna |
| 340 | + ): |
| 341 | + # Cast to make sure we get "NaN" string instead of "NA" |
| 342 | + frame[key] = ser.astype(old_dtype[key]) |
| 343 | + frame.loc[ser.isna(), key] = np.nan |
| 344 | + old_dtype[key] = object # Avoid re-casting |
329 | 345 | elif isinstance(ser.dtype, StringDtype):
|
330 | 346 | # We cast here in case the user passed "category" in
|
331 | 347 | # order to get the correct dtype.categories.dtype
|
332 | 348 | # e.g. test_categorical_dtype_utf16
|
333 |
| - sdt = StringDtype(na_value=np.nan) |
| 349 | + if not using_string_dtype(): |
| 350 | + sdt = np.dtype(object) |
| 351 | + frame[key] = ser.astype(sdt) |
| 352 | + frame.loc[ser.isna(), key] = np.nan |
| 353 | + else: |
| 354 | + sdt = StringDtype(na_value=np.nan) |
| 355 | + frame[key] = frame[key].astype(sdt) |
334 | 356 | new_dtype[key] = sdt # type: ignore[assignment]
|
335 |
| - frame[key] = frame[key].astype(new_dtype[key]) |
336 | 357 |
|
337 | 358 | new_dtype.update(old_dtype)
|
338 | 359 | self.dtype = new_dtype
|
|
0 commit comments