Skip to content

Commit 1d20cc5

Browse files
evangelinehlPingviinituutti
authored andcommitted
BUG: Fix concat series loss of timezone (pandas-dev#24027)
1 parent a3f5976 commit 1d20cc5

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

doc/source/whatsnew/v0.24.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,7 @@ Reshaping
15541554
- Bug in :meth:`DataFrame.append` with a :class:`Series` with a dateutil timezone would raise a ``TypeError`` (:issue:`23682`)
15551555
- Bug in ``Series`` construction when passing no data and ``dtype=str`` (:issue:`22477`)
15561556
- Bug in :func:`cut` with ``bins`` as an overlapping ``IntervalIndex`` where multiple bins were returned per item instead of raising a ``ValueError`` (:issue:`23980`)
1557+
- Bug in :func:`pandas.concat` when joining ``Series`` datetimetz with ``Series`` category would lose timezone (:issue:`23816`)
15571558
- Bug in :meth:`DataFrame.join` when joining on partial MultiIndex would drop names (:issue:`20452`).
15581559

15591560
.. _whatsnew_0240.bug_fixes.sparse:

pandas/core/dtypes/concat.py

+8-10
Original file line numberDiff line numberDiff line change
@@ -191,15 +191,6 @@ def _concat_categorical(to_concat, axis=0):
191191
A single array, preserving the combined dtypes
192192
"""
193193

194-
def _concat_asobject(to_concat):
195-
to_concat = [x.get_values() if is_categorical_dtype(x.dtype)
196-
else np.asarray(x).ravel() for x in to_concat]
197-
res = _concat_compat(to_concat)
198-
if axis == 1:
199-
return res.reshape(1, len(res))
200-
else:
201-
return res
202-
203194
# we could have object blocks and categoricals here
204195
# if we only have a single categoricals then combine everything
205196
# else its a non-compat categorical
@@ -214,7 +205,14 @@ def _concat_asobject(to_concat):
214205
if all(first.is_dtype_equal(other) for other in to_concat[1:]):
215206
return union_categoricals(categoricals)
216207

217-
return _concat_asobject(to_concat)
208+
# extract the categoricals & coerce to object if needed
209+
to_concat = [x.get_values() if is_categorical_dtype(x.dtype)
210+
else np.asarray(x).ravel() if not is_datetime64tz_dtype(x)
211+
else np.asarray(x.astype(object)) for x in to_concat]
212+
result = _concat_compat(to_concat)
213+
if axis == 1:
214+
result = result.reshape(1, len(result))
215+
return result
218216

219217

220218
def union_categoricals(to_union, sort_categories=False, ignore_order=False):

pandas/tests/reshape/test_concat.py

+13
Original file line numberDiff line numberDiff line change
@@ -2552,3 +2552,16 @@ def test_concat_series_name_npscalar_tuple(s1name, s2name):
25522552
result = pd.concat([s1, s2])
25532553
expected = pd.Series({'a': 1, 'b': 2, 'c': 5, 'd': 6})
25542554
tm.assert_series_equal(result, expected)
2555+
2556+
2557+
def test_concat_categorical_tz():
2558+
# GH-23816
2559+
a = pd.Series(pd.date_range('2017-01-01', periods=2, tz='US/Pacific'))
2560+
b = pd.Series(['a', 'b'], dtype='category')
2561+
result = pd.concat([a, b], ignore_index=True)
2562+
expected = pd.Series([
2563+
pd.Timestamp('2017-01-01', tz="US/Pacific"),
2564+
pd.Timestamp('2017-01-02', tz="US/Pacific"),
2565+
'a', 'b'
2566+
])
2567+
tm.assert_series_equal(result, expected)

0 commit comments

Comments
 (0)