From e46c85f8246556d060f396b69bad8041bc9df872 Mon Sep 17 00:00:00 2001 From: Khor Chean Wei Date: Thu, 24 Feb 2022 21:54:45 +0800 Subject: [PATCH 01/20] Update format.py --- pandas/io/formats/format.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 4bc45e290ce4a..0817af3cf15cd 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1622,17 +1622,25 @@ def __init__( def _format_strings(self) -> list[str]: """we by definition have DO NOT have a TZ""" values = self.values + values_shape = values.shape + values = values.ravel() if values.ndim > 1 else values if not isinstance(values, DatetimeIndex): values = DatetimeIndex(values) if self.formatter is not None and callable(self.formatter): - return [self.formatter(x) for x in values] + fmt_values = [self.formatter(x) for x in values] + else: + fmt_values = values._data._format_native_types( + na_rep=self.nat_rep, date_format=self.date_format + ) - fmt_values = values._data._format_native_types( - na_rep=self.nat_rep, date_format=self.date_format - ) - return fmt_values.tolist() + if len(values_shape) > 1: + fmt_values = np.array(fmt_values).reshape(values_shape) + nested_formatter = GenericArrayFormatter(fmt_values) + fmt_values = nested_formatter.get_result() + + return fmt_values class ExtensionArrayFormatter(GenericArrayFormatter): @@ -1810,11 +1818,17 @@ class Datetime64TZFormatter(Datetime64Formatter): def _format_strings(self) -> list[str]: """we by definition have a TZ""" values = self.values.astype(object) + values_shape = values.shape + values = values.ravel() if values.ndim > 1 else values ido = is_dates_only(values) formatter = self.formatter or get_format_datetime64( ido, date_format=self.date_format ) fmt_values = [formatter(x) for x in values] + if len(values_shape) > 1: + fmt_values = np.array(values).reshape(values_shape) + nested_formatter = GenericArrayFormatter(fmt_values) + fmt_values = nested_formatter.get_result() return fmt_values From 0a51d254a63886add0e23fc4ee9c2a5fd2a857a4 Mon Sep 17 00:00:00 2001 From: Khor Chean Wei Date: Thu, 24 Feb 2022 21:55:22 +0800 Subject: [PATCH 02/20] Update test_format.py --- pandas/tests/io/formats/test_format.py | 88 ++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index adcaeba5cfd8d..c2c13afc93018 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -3158,6 +3158,94 @@ def format_func(x): result = formatter.get_result() assert result == ["10:10", "12:12"] + def test_datetime64formatter_2d_array(self): + x = pd.date_range("2018-01-01", periods=10, freq="H").to_numpy() + + formatter = fmt.Datetime64Formatter(x.reshape((5, 2))) + result = formatter.get_result() + assert len(result) == 5 + assert result[0].strip() == "[2018-01-01 00:00:00, 2018-01-01 01:00:00]" + assert result[4].strip() == "[2018-01-01 08:00:00, 2018-01-01 09:00:00]" + + formatter = fmt.Datetime64Formatter(x.reshape((2, 5))) + result = formatter.get_result() + assert len(result) == 2 + assert result[0].strip() == "[2018-01-01 00:00:00, 2018-01-01 01:00:00, 201..." + assert result[1].strip() == "[2018-01-01 05:00:00, 2018-01-01 06:00:00, 201..." + + def test_datetime64formatter_3d_array(self): + x = pd.date_range("2018-01-01", periods=10, freq="H").to_numpy() + + formatter = fmt.Datetime64Formatter(x.reshape((10, 1, 1))) + result = formatter.get_result() + assert len(result) == 10 + assert result[0].strip() == "[[2018-01-01 00:00:00]]" + assert result[9].strip() == "[[2018-01-01 09:00:00]]" + + def test_datetime64formatter_2d_array_format_func(self): + x = pd.date_range("2018-01-01", periods=24, freq="H").to_numpy() + + def format_func(t): + return t.strftime("%H-%m") + + formatter = fmt.Datetime64Formatter(x.reshape((4, 2, 3)), formatter=format_func) + result = formatter.get_result() + assert len(result) == 4 + assert result[0].strip() == "[[00-01, 01-01, 02-01], [03-01, 04-01, 05-01]]" + assert result[3].strip() == "[[18-01, 19-01, 20-01], [21-01, 22-01, 23-01]]" + + +class TestDatetime64TZFormatter: + def test_mixed(self): + utc = dateutil.tz.tzutc() + x = Series( + [ + datetime(2013, 1, 1, tzinfo=utc), + datetime(2013, 1, 1, 12, tzinfo=utc), + pd.NaT, + ] + ) + result = fmt.Datetime64TZFormatter(x).get_result() + assert len(result) == 3 + assert result[0].strip() == "2013-01-01 00:00:00+00:00" + assert result[1].strip() == "2013-01-01 12:00:00+00:00" + assert result[2].strip() == "NaT" + + def test_datetime64formatter_1d_array(self): + x = pd.date_range("2018-01-01", periods=3, freq="H", tz="US/Pacific").to_numpy() + formatter = fmt.Datetime64TZFormatter(x) + result = formatter.get_result() + assert len(result) == 3 + assert result[0].strip() == "2018-01-01 00:00:00-08:00" + assert result[1].strip() == "2018-01-01 01:00:00-08:00" + assert result[2].strip() == "2018-01-01 02:00:00-08:00" + + def test_datetime64formatter_2d_array(self): + x = pd.date_range( + "2018-01-01", periods=10, freq="H", tz="US/Pacific" + ).to_numpy() + formatter = fmt.Datetime64TZFormatter(x.reshape((5, 2))) + result = formatter.get_result() + assert len(result) == 5 + assert result[0].strip() == "[2018-01-01 00:00:00-08:00, 2018-01-01 01:00:0..." + assert result[4].strip() == "[2018-01-01 08:00:00-08:00, 2018-01-01 09:00:0..." + + def test_datetime64formatter_2d_array_format_func(self): + x = pd.date_range( + "2018-01-01", periods=16, freq="H", tz="US/Pacific" + ).to_numpy() + + def format_func(t): + return t.strftime("%H-%m %Z") + + formatter = fmt.Datetime64TZFormatter( + x.reshape((4, 2, 2)), formatter=format_func + ) + result = formatter.get_result() + assert len(result) == 4 + assert result[0].strip() == "[[2018-01-01 00:00:00-08:00, 2018-01-01 01:00:..." + assert result[3].strip() == "[[2018-01-01 12:00:00-08:00, 2018-01-01 13:00:..." + class TestNaTFormatting: def test_repr(self): From c6bf639e7bd74072e34bb017c088bf91ae47f96c Mon Sep 17 00:00:00 2001 From: Khor Chean Wei Date: Thu, 24 Feb 2022 22:54:37 +0800 Subject: [PATCH 03/20] pre commit --- pandas/tests/io/formats/test_format.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index c2c13afc93018..5ed395c34ffa4 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -3159,7 +3159,7 @@ def format_func(x): assert result == ["10:10", "12:12"] def test_datetime64formatter_2d_array(self): - x = pd.date_range("2018-01-01", periods=10, freq="H").to_numpy() + x = date_range("2018-01-01", periods=10, freq="H").to_numpy() formatter = fmt.Datetime64Formatter(x.reshape((5, 2))) result = formatter.get_result() @@ -3174,7 +3174,7 @@ def test_datetime64formatter_2d_array(self): assert result[1].strip() == "[2018-01-01 05:00:00, 2018-01-01 06:00:00, 201..." def test_datetime64formatter_3d_array(self): - x = pd.date_range("2018-01-01", periods=10, freq="H").to_numpy() + x = date_range("2018-01-01", periods=10, freq="H").to_numpy() formatter = fmt.Datetime64Formatter(x.reshape((10, 1, 1))) result = formatter.get_result() @@ -3183,7 +3183,7 @@ def test_datetime64formatter_3d_array(self): assert result[9].strip() == "[[2018-01-01 09:00:00]]" def test_datetime64formatter_2d_array_format_func(self): - x = pd.date_range("2018-01-01", periods=24, freq="H").to_numpy() + x = date_range("2018-01-01", periods=24, freq="H").to_numpy() def format_func(t): return t.strftime("%H-%m") @@ -3212,7 +3212,7 @@ def test_mixed(self): assert result[2].strip() == "NaT" def test_datetime64formatter_1d_array(self): - x = pd.date_range("2018-01-01", periods=3, freq="H", tz="US/Pacific").to_numpy() + x = date_range("2018-01-01", periods=3, freq="H", tz="US/Pacific").to_numpy() formatter = fmt.Datetime64TZFormatter(x) result = formatter.get_result() assert len(result) == 3 @@ -3221,9 +3221,7 @@ def test_datetime64formatter_1d_array(self): assert result[2].strip() == "2018-01-01 02:00:00-08:00" def test_datetime64formatter_2d_array(self): - x = pd.date_range( - "2018-01-01", periods=10, freq="H", tz="US/Pacific" - ).to_numpy() + x = date_range("2018-01-01", periods=10, freq="H", tz="US/Pacific").to_numpy() formatter = fmt.Datetime64TZFormatter(x.reshape((5, 2))) result = formatter.get_result() assert len(result) == 5 @@ -3231,9 +3229,7 @@ def test_datetime64formatter_2d_array(self): assert result[4].strip() == "[2018-01-01 08:00:00-08:00, 2018-01-01 09:00:0..." def test_datetime64formatter_2d_array_format_func(self): - x = pd.date_range( - "2018-01-01", periods=16, freq="H", tz="US/Pacific" - ).to_numpy() + x = date_range("2018-01-01", periods=16, freq="H", tz="US/Pacific").to_numpy() def format_func(t): return t.strftime("%H-%m %Z") From f857db842c32c69eb20880f919e71d2dc1aa0919 Mon Sep 17 00:00:00 2001 From: Khor Chean Wei Date: Thu, 24 Feb 2022 23:25:59 +0800 Subject: [PATCH 04/20] Update test_format.py --- pandas/tests/io/formats/test_format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 5ed395c34ffa4..7b916fb2ea0f5 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -3202,7 +3202,7 @@ def test_mixed(self): [ datetime(2013, 1, 1, tzinfo=utc), datetime(2013, 1, 1, 12, tzinfo=utc), - pd.NaT, + NaT, ] ) result = fmt.Datetime64TZFormatter(x).get_result() From 2be9fd2822c913839d3eadb13717a2b0647b89f6 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Fri, 25 Feb 2022 20:32:41 +0800 Subject: [PATCH 05/20] incompatible types in assignment --- pandas/io/formats/format.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 0817af3cf15cd..df05935ccfc99 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1636,7 +1636,7 @@ def _format_strings(self) -> list[str]: ) if len(values_shape) > 1: - fmt_values = np.array(fmt_values).reshape(values_shape) + fmt_values = np.reshape(fmt_values, values_shape) nested_formatter = GenericArrayFormatter(fmt_values) fmt_values = nested_formatter.get_result() @@ -1826,7 +1826,7 @@ def _format_strings(self) -> list[str]: ) fmt_values = [formatter(x) for x in values] if len(values_shape) > 1: - fmt_values = np.array(values).reshape(values_shape) + fmt_values = np.reshape(values, values_shape) nested_formatter = GenericArrayFormatter(fmt_values) fmt_values = nested_formatter.get_result() From d286682b2ca70d4bec7c1b1b1162e3f7920af723 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Sat, 26 Feb 2022 13:10:48 +0800 Subject: [PATCH 06/20] add --- pandas/core/dtypes/astype.py | 2 ++ pandas/io/formats/format.py | 13 +++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/pandas/core/dtypes/astype.py b/pandas/core/dtypes/astype.py index 1e78bf0cd33ae..1028559402481 100644 --- a/pandas/core/dtypes/astype.py +++ b/pandas/core/dtypes/astype.py @@ -118,6 +118,8 @@ def astype_nansafe( # allow frequency conversions if dtype.kind == "M": + if dtype == " list[str]: values = DatetimeIndex(values) if self.formatter is not None and callable(self.formatter): - fmt_values = [self.formatter(x) for x in values] + values = [self.formatter(x) for x in values] else: - fmt_values = values._data._format_native_types( + values = values._data._format_native_types( na_rep=self.nat_rep, date_format=self.date_format ) if len(values_shape) > 1: - fmt_values = np.reshape(fmt_values, values_shape) + fmt_values = np.reshape(values, values_shape) nested_formatter = GenericArrayFormatter(fmt_values) fmt_values = nested_formatter.get_result() + else: + fmt_values = values return fmt_values @@ -1824,11 +1826,14 @@ def _format_strings(self) -> list[str]: formatter = self.formatter or get_format_datetime64( ido, date_format=self.date_format ) - fmt_values = [formatter(x) for x in values] + if len(values_shape) > 1: fmt_values = np.reshape(values, values_shape) nested_formatter = GenericArrayFormatter(fmt_values) fmt_values = nested_formatter.get_result() + else: + values = [formatter(x) for x in values] + fmt_values = values return fmt_values From 6eea97675f5fa30798fc70ff5addfed35dfaa047 Mon Sep 17 00:00:00 2001 From: Khor Chean Wei Date: Sat, 26 Feb 2022 14:20:30 +0800 Subject: [PATCH 07/20] Update astype.py --- pandas/core/dtypes/astype.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pandas/core/dtypes/astype.py b/pandas/core/dtypes/astype.py index 1028559402481..1e78bf0cd33ae 100644 --- a/pandas/core/dtypes/astype.py +++ b/pandas/core/dtypes/astype.py @@ -118,8 +118,6 @@ def astype_nansafe( # allow frequency conversions if dtype.kind == "M": - if dtype == " Date: Sat, 26 Feb 2022 15:24:08 +0800 Subject: [PATCH 08/20] Incompatible return value type --- pandas/io/formats/format.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 2f184c3c66406..5ef77281d5dda 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1642,6 +1642,9 @@ def _format_strings(self) -> list[str]: else: fmt_values = values + if isinstance(fmt_values, np.ndarray): + fmt_values = fmt_values.tolist() + return fmt_values @@ -1835,6 +1838,9 @@ def _format_strings(self) -> list[str]: values = [formatter(x) for x in values] fmt_values = values + if isinstance(fmt_values, np.ndarray): + fmt_values = fmt_values.tolist() + return fmt_values From 00a7e7e3c02d07b5e7ba531541dee2661b552c22 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Sun, 27 Feb 2022 23:37:07 +0800 Subject: [PATCH 09/20] change to list(fmt_values) --- pandas/io/formats/format.py | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 5ef77281d5dda..a9ed3bdc7d809 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1635,6 +1635,10 @@ def _format_strings(self) -> list[str]: na_rep=self.nat_rep, date_format=self.date_format ) + fmt_values = self._reshape_formatted_strings(values, values_shape) + return fmt_values + + def _reshape_formatted_strings(self, values, values_shape): if len(values_shape) > 1: fmt_values = np.reshape(values, values_shape) nested_formatter = GenericArrayFormatter(fmt_values) @@ -1642,10 +1646,7 @@ def _format_strings(self) -> list[str]: else: fmt_values = values - if isinstance(fmt_values, np.ndarray): - fmt_values = fmt_values.tolist() - - return fmt_values + return list(fmt_values) class ExtensionArrayFormatter(GenericArrayFormatter): @@ -1830,17 +1831,10 @@ def _format_strings(self) -> list[str]: ido, date_format=self.date_format ) - if len(values_shape) > 1: - fmt_values = np.reshape(values, values_shape) - nested_formatter = GenericArrayFormatter(fmt_values) - fmt_values = nested_formatter.get_result() - else: + if len(values_shape) == 1: values = [formatter(x) for x in values] - fmt_values = values - - if isinstance(fmt_values, np.ndarray): - fmt_values = fmt_values.tolist() + fmt_values = self._reshape_formatted_strings(values, values_shape) return fmt_values From 065001f13c7674bd5cd8784f0fe0cde4795dc8b1 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Thu, 3 Mar 2022 23:11:32 +0800 Subject: [PATCH 10/20] add --- pandas/io/formats/format.py | 31 ++++++++------------------ pandas/tests/io/formats/test_format.py | 5 +++-- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index a9ed3bdc7d809..bfc376cd17600 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1621,31 +1621,21 @@ def __init__( def _format_strings(self) -> list[str]: """we by definition have DO NOT have a TZ""" + values = self.values - values_shape = values.shape - values = values.ravel() if values.ndim > 1 else values if not isinstance(values, DatetimeIndex): values = DatetimeIndex(values) if self.formatter is not None and callable(self.formatter): - values = [self.formatter(x) for x in values] + fmt_values = np.frompyfunc(self.formatter, 1, 1)(values) else: - values = values._data._format_native_types( + fmt_values = values._data._format_native_types( na_rep=self.nat_rep, date_format=self.date_format ) - fmt_values = self._reshape_formatted_strings(values, values_shape) - return fmt_values - - def _reshape_formatted_strings(self, values, values_shape): - if len(values_shape) > 1: - fmt_values = np.reshape(values, values_shape) - nested_formatter = GenericArrayFormatter(fmt_values) - fmt_values = nested_formatter.get_result() - else: - fmt_values = values - + nested_formatter = GenericArrayFormatter(fmt_values) + fmt_values = nested_formatter.get_result() return list(fmt_values) @@ -1824,18 +1814,15 @@ class Datetime64TZFormatter(Datetime64Formatter): def _format_strings(self) -> list[str]: """we by definition have a TZ""" values = self.values.astype(object) - values_shape = values.shape - values = values.ravel() if values.ndim > 1 else values ido = is_dates_only(values) formatter = self.formatter or get_format_datetime64( ido, date_format=self.date_format ) + fmt_values = np.frompyfunc(formatter, 1, 1)(values) - if len(values_shape) == 1: - values = [formatter(x) for x in values] - - fmt_values = self._reshape_formatted_strings(values, values_shape) - return fmt_values + nested_formatter = GenericArrayFormatter(fmt_values) + fmt_values = nested_formatter.get_result() + return list(fmt_values) class Timedelta64Formatter(GenericArrayFormatter): diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 7b916fb2ea0f5..371604e992588 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -3186,6 +3186,7 @@ def test_datetime64formatter_2d_array_format_func(self): x = date_range("2018-01-01", periods=24, freq="H").to_numpy() def format_func(t): + t = pd.to_datetime(t) return t.strftime("%H-%m") formatter = fmt.Datetime64Formatter(x.reshape((4, 2, 3)), formatter=format_func) @@ -3239,8 +3240,8 @@ def format_func(t): ) result = formatter.get_result() assert len(result) == 4 - assert result[0].strip() == "[[2018-01-01 00:00:00-08:00, 2018-01-01 01:00:..." - assert result[3].strip() == "[[2018-01-01 12:00:00-08:00, 2018-01-01 13:00:..." + assert result[0].strip() == "[[00-01 PST, 01-01 PST], [02-01 PST, 03-01 PST]]" + assert result[3].strip() == "[[12-01 PST, 13-01 PST], [14-01 PST, 15-01 PST]]" class TestNaTFormatting: From 654b01a13a91419860a7bb5e35a730c958c30d5e Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Thu, 3 Mar 2022 23:28:17 +0800 Subject: [PATCH 11/20] add --- pandas/tests/io/formats/test_format.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 371604e992588..ba1bf3ababab1 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -3186,7 +3186,6 @@ def test_datetime64formatter_2d_array_format_func(self): x = date_range("2018-01-01", periods=24, freq="H").to_numpy() def format_func(t): - t = pd.to_datetime(t) return t.strftime("%H-%m") formatter = fmt.Datetime64Formatter(x.reshape((4, 2, 3)), formatter=format_func) From 55f49080ba29fc7436228c1c036d3abc4909fd8d Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Sat, 5 Mar 2022 15:17:56 +0800 Subject: [PATCH 12/20] add --- pandas/io/formats/format.py | 4 ++-- pandas/tests/io/formats/test_format.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index bfc376cd17600..24612dd349ea6 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1628,13 +1628,13 @@ def _format_strings(self) -> list[str]: values = DatetimeIndex(values) if self.formatter is not None and callable(self.formatter): - fmt_values = np.frompyfunc(self.formatter, 1, 1)(values) + fmt_values = [self.formatter(x) for x in values] else: fmt_values = values._data._format_native_types( na_rep=self.nat_rep, date_format=self.date_format ) - nested_formatter = GenericArrayFormatter(fmt_values) + nested_formatter = GenericArrayFormatter(np.array(fmt_values)) fmt_values = nested_formatter.get_result() return list(fmt_values) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index ba1bf3ababab1..ad97a212e14b1 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -3182,7 +3182,7 @@ def test_datetime64formatter_3d_array(self): assert result[0].strip() == "[[2018-01-01 00:00:00]]" assert result[9].strip() == "[[2018-01-01 09:00:00]]" - def test_datetime64formatter_2d_array_format_func(self): + def test_datetime64formatter_3d_array_format_func(self): x = date_range("2018-01-01", periods=24, freq="H").to_numpy() def format_func(t): From fed06941f2069a30e7559637af2aaeebcb13d2ee Mon Sep 17 00:00:00 2001 From: Khor Chean Wei Date: Sat, 5 Mar 2022 15:21:51 +0800 Subject: [PATCH 13/20] Update test_format.py --- pandas/tests/io/formats/test_format.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index ad97a212e14b1..71531ccf4e02a 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -3159,6 +3159,7 @@ def format_func(x): assert result == ["10:10", "12:12"] def test_datetime64formatter_2d_array(self): + # GH#38390 x = date_range("2018-01-01", periods=10, freq="H").to_numpy() formatter = fmt.Datetime64Formatter(x.reshape((5, 2))) @@ -3174,6 +3175,7 @@ def test_datetime64formatter_2d_array(self): assert result[1].strip() == "[2018-01-01 05:00:00, 2018-01-01 06:00:00, 201..." def test_datetime64formatter_3d_array(self): + # GH#38390 x = date_range("2018-01-01", periods=10, freq="H").to_numpy() formatter = fmt.Datetime64Formatter(x.reshape((10, 1, 1))) @@ -3183,6 +3185,7 @@ def test_datetime64formatter_3d_array(self): assert result[9].strip() == "[[2018-01-01 09:00:00]]" def test_datetime64formatter_3d_array_format_func(self): + # GH#38390 x = date_range("2018-01-01", periods=24, freq="H").to_numpy() def format_func(t): @@ -3197,6 +3200,7 @@ def format_func(t): class TestDatetime64TZFormatter: def test_mixed(self): + # GH#38390 utc = dateutil.tz.tzutc() x = Series( [ @@ -3212,6 +3216,7 @@ def test_mixed(self): assert result[2].strip() == "NaT" def test_datetime64formatter_1d_array(self): + # GH#38390 x = date_range("2018-01-01", periods=3, freq="H", tz="US/Pacific").to_numpy() formatter = fmt.Datetime64TZFormatter(x) result = formatter.get_result() @@ -3221,6 +3226,7 @@ def test_datetime64formatter_1d_array(self): assert result[2].strip() == "2018-01-01 02:00:00-08:00" def test_datetime64formatter_2d_array(self): + # GH#38390 x = date_range("2018-01-01", periods=10, freq="H", tz="US/Pacific").to_numpy() formatter = fmt.Datetime64TZFormatter(x.reshape((5, 2))) result = formatter.get_result() @@ -3229,6 +3235,7 @@ def test_datetime64formatter_2d_array(self): assert result[4].strip() == "[2018-01-01 08:00:00-08:00, 2018-01-01 09:00:0..." def test_datetime64formatter_2d_array_format_func(self): + # GH#38390 x = date_range("2018-01-01", periods=16, freq="H", tz="US/Pacific").to_numpy() def format_func(t): From a77eb63b291a686fa80ab352e273840ac89c0745 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Sat, 5 Mar 2022 16:03:44 +0800 Subject: [PATCH 14/20] add ndim condition --- pandas/io/formats/format.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 24612dd349ea6..e72af73867a2e 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1819,9 +1819,9 @@ def _format_strings(self) -> list[str]: ido, date_format=self.date_format ) fmt_values = np.frompyfunc(formatter, 1, 1)(values) - - nested_formatter = GenericArrayFormatter(fmt_values) - fmt_values = nested_formatter.get_result() + if fmt_values.ndim > 1: + nested_formatter = GenericArrayFormatter(fmt_values) + fmt_values = nested_formatter.get_result() return list(fmt_values) From 54e13167056a9f3d8911c7fdbb27c312ba288500 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Sat, 5 Mar 2022 21:36:54 +0800 Subject: [PATCH 15/20] 2d case --- pandas/io/formats/format.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index e72af73867a2e..d6a97eb592f4c 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1634,8 +1634,10 @@ def _format_strings(self) -> list[str]: na_rep=self.nat_rep, date_format=self.date_format ) - nested_formatter = GenericArrayFormatter(np.array(fmt_values)) - fmt_values = nested_formatter.get_result() + if fmt_values.ndim > 1: + nested_formatter = GenericArrayFormatter(fmt_values) + fmt_values = nested_formatter.get_result() + return list(fmt_values) From 7fed7309c152e8b439e1cc3856af2a0224ca00f6 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Sat, 5 Mar 2022 22:36:21 +0800 Subject: [PATCH 16/20] change numpy type --- pandas/io/formats/format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index d6a97eb592f4c..6bbe36b2a641c 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1628,7 +1628,7 @@ def _format_strings(self) -> list[str]: values = DatetimeIndex(values) if self.formatter is not None and callable(self.formatter): - fmt_values = [self.formatter(x) for x in values] + fmt_values = np.array([self.formatter(x) for x in values]) else: fmt_values = values._data._format_native_types( na_rep=self.nat_rep, date_format=self.date_format From dee7364a9be92797dfaffd9d85809fcd7324d06f Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Tue, 8 Mar 2022 23:47:27 +0800 Subject: [PATCH 17/20] tidy --- pandas/io/formats/format.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 65fa5658671d5..a585995769b2e 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1623,7 +1623,6 @@ def _format_strings(self) -> list[str]: """we by definition have DO NOT have a TZ""" values = self.values - if not isinstance(values, DatetimeIndex): values = DatetimeIndex(values) From 95b423ddd267471a6c9f74e5cfdceadc91e41dd2 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Thu, 10 Mar 2022 21:01:33 +0800 Subject: [PATCH 18/20] nested format --- pandas/io/formats/format.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index a585995769b2e..a468ad75de89e 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1635,9 +1635,9 @@ def _format_strings(self) -> list[str]: if fmt_values.ndim > 1: nested_formatter = GenericArrayFormatter(fmt_values) - fmt_values = nested_formatter.get_result() + fmt_values = list(nested_formatter.get_result()) - return list(fmt_values) + return fmt_values class ExtensionArrayFormatter(GenericArrayFormatter): @@ -1819,8 +1819,8 @@ def _format_strings(self) -> list[str]: fmt_values = np.frompyfunc(formatter, 1, 1)(values) if fmt_values.ndim > 1: nested_formatter = GenericArrayFormatter(fmt_values) - fmt_values = nested_formatter.get_result() - return list(fmt_values) + fmt_values = list(nested_formatter.get_result()) + return fmt_values class Timedelta64Formatter(GenericArrayFormatter): From 7451562e49f28e22c2851bd5c3aa1aca73443b04 Mon Sep 17 00:00:00 2001 From: "chean.wei.khor" Date: Thu, 10 Mar 2022 23:11:45 +0800 Subject: [PATCH 19/20] expression and variable --- pandas/io/formats/format.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index a468ad75de89e..11415dd35b65d 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1635,7 +1635,7 @@ def _format_strings(self) -> list[str]: if fmt_values.ndim > 1: nested_formatter = GenericArrayFormatter(fmt_values) - fmt_values = list(nested_formatter.get_result()) + return list(nested_formatter.get_result()) return fmt_values @@ -1819,7 +1819,8 @@ def _format_strings(self) -> list[str]: fmt_values = np.frompyfunc(formatter, 1, 1)(values) if fmt_values.ndim > 1: nested_formatter = GenericArrayFormatter(fmt_values) - fmt_values = list(nested_formatter.get_result()) + return list(nested_formatter.get_result()) + return fmt_values From f71e11f22048912ecb5c0f8280a4fd381a1a7763 Mon Sep 17 00:00:00 2001 From: Khor Chean Wei Date: Fri, 11 Mar 2022 00:22:34 +0800 Subject: [PATCH 20/20] Update format.py --- pandas/io/formats/format.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 11415dd35b65d..116fbb86f2228 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1637,7 +1637,7 @@ def _format_strings(self) -> list[str]: nested_formatter = GenericArrayFormatter(fmt_values) return list(nested_formatter.get_result()) - return fmt_values + return list(fmt_values) class ExtensionArrayFormatter(GenericArrayFormatter): @@ -1821,7 +1821,7 @@ def _format_strings(self) -> list[str]: nested_formatter = GenericArrayFormatter(fmt_values) return list(nested_formatter.get_result()) - return fmt_values + return list(fmt_values) class Timedelta64Formatter(GenericArrayFormatter):