Skip to content

Commit d4dff29

Browse files
Bug: Fix convert_dtypes not preserving timezone details for ArrowDtype (#60952)
* modified the files according to bug#60237 * Update doc/source/whatsnew/v3.0.0.rst Co-authored-by: Matthew Roeschke <[email protected]> * moved test case to frame and serier folders * fix pyarrow import error --------- Co-authored-by: Matthew Roeschke <[email protected]>
1 parent 5b2cddb commit d4dff29

File tree

4 files changed

+28
-1
lines changed

4 files changed

+28
-1
lines changed

doc/source/whatsnew/v3.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ Conversion
670670
- Bug in :meth:`DataFrame.astype` not casting ``values`` for Arrow-based dictionary dtype correctly (:issue:`58479`)
671671
- Bug in :meth:`DataFrame.update` bool dtype being converted to object (:issue:`55509`)
672672
- Bug in :meth:`Series.astype` might modify read-only array inplace when casting to a string dtype (:issue:`57212`)
673+
- Bug in :meth:`Series.convert_dtypes` and :meth:`DataFrame.convert_dtypes` removing timezone information for objects with :class:`ArrowDtype` (:issue:`60237`)
673674
- Bug in :meth:`Series.reindex` not maintaining ``float32`` type when a ``reindex`` introduces a missing value (:issue:`45857`)
674675

675676
Strings

pandas/core/dtypes/cast.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,7 @@ def convert_dtypes(
11131113
else:
11141114
inferred_dtype = input_array.dtype
11151115

1116-
if dtype_backend == "pyarrow":
1116+
if dtype_backend == "pyarrow" and not isinstance(inferred_dtype, ArrowDtype):
11171117
from pandas.core.arrays.arrow.array import to_pyarrow_type
11181118
from pandas.core.arrays.string_ import StringDtype
11191119

pandas/tests/frame/methods/test_convert_dtypes.py

+15
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,18 @@ def test_convert_dtypes_from_arrow(self):
196196
result = df.convert_dtypes()
197197
expected = df.astype({"a": "string[python]"})
198198
tm.assert_frame_equal(result, expected)
199+
200+
def test_convert_dtype_pyarrow_timezone_preserve(self):
201+
# GH 60237
202+
pytest.importorskip("pyarrow")
203+
df = pd.DataFrame(
204+
{
205+
"timestamps": pd.Series(
206+
pd.to_datetime(range(5), utc=True, unit="h"),
207+
dtype="timestamp[ns, tz=UTC][pyarrow]",
208+
)
209+
}
210+
)
211+
result = df.convert_dtypes(dtype_backend="pyarrow")
212+
expected = df.copy()
213+
tm.assert_frame_equal(result, expected)

pandas/tests/series/methods/test_convert_dtypes.py

+11
Original file line numberDiff line numberDiff line change
@@ -297,3 +297,14 @@ def test_convert_dtypes_pyarrow_null(self):
297297
result = ser.convert_dtypes(dtype_backend="pyarrow")
298298
expected = pd.Series([None, None], dtype=pd.ArrowDtype(pa.null()))
299299
tm.assert_series_equal(result, expected)
300+
301+
def test_convert_dtype_pyarrow_timezone_preserve(self):
302+
# GH 60237
303+
pytest.importorskip("pyarrow")
304+
ser = pd.Series(
305+
pd.to_datetime(range(5), utc=True, unit="h"),
306+
dtype="timestamp[ns, tz=UTC][pyarrow]",
307+
)
308+
result = ser.convert_dtypes(dtype_backend="pyarrow")
309+
expected = ser.copy()
310+
tm.assert_series_equal(result, expected)

0 commit comments

Comments
 (0)