Skip to content

Commit 2245217

Browse files
authored
This fix enables you to preserve the datetime precision when using the melt method. (pandas-dev#55270)
This fix enables you to preserve the datetime precision when using the melt method. It fixes the issues raised in pandas-dev#55254.
1 parent 8664572 commit 2245217

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

doc/source/whatsnew/v2.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ Bug fixes
254254
- Bug in :class:`AbstractHolidayCalendar` where timezone data was not propagated when computing holiday observances (:issue:`54580`)
255255
- Bug in :class:`pandas.core.window.Rolling` where duplicate datetimelike indexes are treated as consecutive rather than equal with ``closed='left'`` and ``closed='neither'`` (:issue:`20712`)
256256
- Bug in :meth:`DataFrame.apply` where passing ``raw=True`` ignored ``args`` passed to the applied function (:issue:`55009`)
257+
- Bug in :meth:`pandas.DataFrame.melt` where it would not preserve the datetime (:issue:`55254`)
257258
- Bug in :meth:`pandas.read_excel` with a ODS file without cached formatted cell for float values (:issue:`55219`)
258259

259260
Categorical

pandas/core/reshape/melt.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ def melt(
134134

135135
mcolumns = id_vars + var_name + [value_name]
136136

137-
if frame.shape[1] > 0:
137+
if frame.shape[1] > 0 and not any(
138+
not isinstance(dt, np.dtype) and dt._supports_2d for dt in frame.dtypes
139+
):
138140
mdata[value_name] = concat(
139141
[frame.iloc[:, i] for i in range(frame.shape[1])]
140142
).values

pandas/tests/reshape/test_melt.py

+41
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,47 @@ def test_melt_ea_columns(self):
459459
)
460460
tm.assert_frame_equal(result, expected)
461461

462+
def test_melt_preserves_datetime(self):
463+
df = DataFrame(
464+
data=[
465+
{
466+
"type": "A0",
467+
"start_date": pd.Timestamp("2023/03/01", tz="Asia/Tokyo"),
468+
"end_date": pd.Timestamp("2023/03/10", tz="Asia/Tokyo"),
469+
},
470+
{
471+
"type": "A1",
472+
"start_date": pd.Timestamp("2023/03/01", tz="Asia/Tokyo"),
473+
"end_date": pd.Timestamp("2023/03/11", tz="Asia/Tokyo"),
474+
},
475+
],
476+
index=["aaaa", "bbbb"],
477+
)
478+
result = df.melt(
479+
id_vars=["type"],
480+
value_vars=["start_date", "end_date"],
481+
var_name="start/end",
482+
value_name="date",
483+
)
484+
expected = DataFrame(
485+
{
486+
"type": {0: "A0", 1: "A1", 2: "A0", 3: "A1"},
487+
"start/end": {
488+
0: "start_date",
489+
1: "start_date",
490+
2: "end_date",
491+
3: "end_date",
492+
},
493+
"date": {
494+
0: pd.Timestamp("2023-03-01 00:00:00+0900", tz="Asia/Tokyo"),
495+
1: pd.Timestamp("2023-03-01 00:00:00+0900", tz="Asia/Tokyo"),
496+
2: pd.Timestamp("2023-03-10 00:00:00+0900", tz="Asia/Tokyo"),
497+
3: pd.Timestamp("2023-03-11 00:00:00+0900", tz="Asia/Tokyo"),
498+
},
499+
}
500+
)
501+
tm.assert_frame_equal(result, expected)
502+
462503

463504
class TestLreshape:
464505
def test_pairs(self):

0 commit comments

Comments
 (0)