Skip to content

Commit b8181f4

Browse files
jorisvandenbosschejbrockmendel
authored andcommitted
REGR: append tz-aware DataFrame with tz-naive values (pandas-dev#36115)
1 parent c67b707 commit b8181f4

File tree

4 files changed

+28
-4
lines changed

4 files changed

+28
-4
lines changed

doc/source/whatsnew/v1.1.2.rst

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Fixed regressions
1616
~~~~~~~~~~~~~~~~~
1717
- Regression in :meth:`DatetimeIndex.intersection` incorrectly raising ``AssertionError`` when intersecting against a list (:issue:`35876`)
1818
- Fix regression in updating a column inplace (e.g. using ``df['col'].fillna(.., inplace=True)``) (:issue:`35731`)
19+
- Fix regression in :meth:`DataFrame.append` mixing tz-aware and tz-naive datetime columns (:issue:`35460`)
1920
- Performance regression for :meth:`RangeIndex.format` (:issue:`35712`)
2021
- Regression where :meth:`MultiIndex.get_loc` would return a slice spanning the full index when passed an empty list (:issue:`35878`)
2122
- Fix regression in invalid cache after an indexing operation; this can manifest when setting which does not update the data (:issue:`35521`)

pandas/core/dtypes/concat.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -148,15 +148,17 @@ def is_nonempty(x) -> bool:
148148
any_ea = any(is_extension_array_dtype(x.dtype) for x in to_concat)
149149

150150
if any_ea:
151+
# we ignore axis here, as internally concatting with EAs is always
152+
# for axis=0
151153
if not single_dtype:
152154
target_dtype = find_common_type([x.dtype for x in to_concat])
153155
to_concat = [_cast_to_common_type(arr, target_dtype) for arr in to_concat]
154156

155-
if isinstance(to_concat[0], ExtensionArray) and axis == 0:
157+
if isinstance(to_concat[0], ExtensionArray):
156158
cls = type(to_concat[0])
157159
return cls._concat_same_type(to_concat)
158160
else:
159-
return np.concatenate(to_concat, axis=axis)
161+
return np.concatenate(to_concat)
160162

161163
elif _contains_datetime or "timedelta" in typs:
162164
return concat_datetime(to_concat, axis=axis, typs=typs)

pandas/core/internals/concat.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from pandas.core.dtypes.missing import isna
2525

2626
import pandas.core.algorithms as algos
27-
from pandas.core.arrays import ExtensionArray
27+
from pandas.core.arrays import DatetimeArray, ExtensionArray
2828
from pandas.core.internals.blocks import make_block
2929
from pandas.core.internals.managers import BlockManager
3030

@@ -335,9 +335,13 @@ def _concatenate_join_units(join_units, concat_axis, copy):
335335
# the non-EA values are 2D arrays with shape (1, n)
336336
to_concat = [t if isinstance(t, ExtensionArray) else t[0, :] for t in to_concat]
337337
concat_values = concat_compat(to_concat, axis=0)
338-
if not isinstance(concat_values, ExtensionArray):
338+
if not isinstance(concat_values, ExtensionArray) or (
339+
isinstance(concat_values, DatetimeArray) and concat_values.tz is None
340+
):
339341
# if the result of concat is not an EA but an ndarray, reshape to
340342
# 2D to put it a non-EA Block
343+
# special case DatetimeArray, which *is* an EA, but is put in a
344+
# consolidated 2D block
341345
concat_values = np.atleast_2d(concat_values)
342346
else:
343347
concat_values = concat_compat(to_concat, axis=concat_axis)

pandas/tests/reshape/test_concat.py

+17
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,23 @@ def test_append_empty_frame_to_series_with_dateutil_tz(self):
11101110
result = df.append([s, s], ignore_index=True)
11111111
tm.assert_frame_equal(result, expected)
11121112

1113+
def test_append_empty_tz_frame_with_datetime64ns(self):
1114+
# https://github.com/pandas-dev/pandas/issues/35460
1115+
df = pd.DataFrame(columns=["a"]).astype("datetime64[ns, UTC]")
1116+
1117+
# pd.NaT gets inferred as tz-naive, so append result is tz-naive
1118+
result = df.append({"a": pd.NaT}, ignore_index=True)
1119+
expected = pd.DataFrame({"a": [pd.NaT]}).astype("datetime64[ns]")
1120+
tm.assert_frame_equal(result, expected)
1121+
1122+
# also test with typed value to append
1123+
df = pd.DataFrame(columns=["a"]).astype("datetime64[ns, UTC]")
1124+
result = df.append(
1125+
pd.Series({"a": pd.NaT}, dtype="datetime64[ns]"), ignore_index=True
1126+
)
1127+
expected = pd.DataFrame({"a": [pd.NaT]}).astype("datetime64[ns]")
1128+
tm.assert_frame_equal(result, expected)
1129+
11131130

11141131
class TestConcatenate:
11151132
def test_concat_copy(self):

0 commit comments

Comments
 (0)