From c687363bb4ee8a199a57c64339ceb14160255326 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Thu, 28 Jul 2022 13:42:09 -0700 Subject: [PATCH 1/3] REF: Change _NULL_DESCRIPTION[datetime] to use NaT sentinel --- pandas/core/exchange/column.py | 2 +- pandas/core/exchange/dataframe_protocol.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/exchange/column.py b/pandas/core/exchange/column.py index c2a1cfe766b22..7b6becbad4f5d 100644 --- a/pandas/core/exchange/column.py +++ b/pandas/core/exchange/column.py @@ -38,7 +38,7 @@ _NULL_DESCRIPTION = { DtypeKind.FLOAT: (ColumnNullType.USE_NAN, None), - DtypeKind.DATETIME: (ColumnNullType.USE_NAN, None), + DtypeKind.DATETIME: (ColumnNullType.USE_SENTINEL, pd.NaT), DtypeKind.INT: (ColumnNullType.NON_NULLABLE, None), DtypeKind.UINT: (ColumnNullType.NON_NULLABLE, None), DtypeKind.BOOL: (ColumnNullType.NON_NULLABLE, None), diff --git a/pandas/core/exchange/dataframe_protocol.py b/pandas/core/exchange/dataframe_protocol.py index 367b906332741..95ff012fce2ab 100644 --- a/pandas/core/exchange/dataframe_protocol.py +++ b/pandas/core/exchange/dataframe_protocol.py @@ -70,7 +70,7 @@ class ColumnNullType(enum.IntEnum): NON_NULLABLE : int Non-nullable column. USE_NAN : int - Use explicit float NaN/NaT value. + Use explicit float NaN value. USE_SENTINEL : int Sentinel value besides NaN/NaT. USE_BITMASK : int From 3ad429e616fd7fcb796a62149ab0d94d8d9d3353 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Mon, 1 Aug 2022 10:56:41 -0700 Subject: [PATCH 2/3] Add test --- pandas/tests/interchange/test_impl.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pandas/tests/interchange/test_impl.py b/pandas/tests/interchange/test_impl.py index 5168e1acc8e7e..209750cf3f510 100644 --- a/pandas/tests/interchange/test_impl.py +++ b/pandas/tests/interchange/test_impl.py @@ -176,3 +176,13 @@ def test_nonstring_object(): col = df.__dataframe__().get_column_by_name("A") with pytest.raises(NotImplementedError, match="not supported yet"): col.dtype + + +def test_datetime(): + df = pd.DataFrame({"A": [pd.Timestamp("2022-01-01"), pd.NaT]}) + col = df.__dataframe__().get_column_by_name("A") + + assert col.size == 2 + assert col.null_count == 1 + assert col.dtype[0] == DtypeKind.DATETIME + assert col.describe_null == (ColumnNullType.USE_SENTINEL, pd.NaT) From c8075c0830c14c656505ab45f48ef7f3d8c4812e Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Mon, 8 Aug 2022 21:57:30 -0700 Subject: [PATCH 3/3] Add roundtrip test and change to use iNaT --- pandas/core/interchange/column.py | 3 ++- pandas/tests/interchange/test_impl.py | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pandas/core/interchange/column.py b/pandas/core/interchange/column.py index 3f9792197959a..9ba237a94b8fe 100644 --- a/pandas/core/interchange/column.py +++ b/pandas/core/interchange/column.py @@ -5,6 +5,7 @@ import numpy as np from pandas._libs.lib import infer_dtype +from pandas._libs.tslibs import iNaT from pandas.util._decorators import cache_readonly import pandas as pd @@ -38,7 +39,7 @@ _NULL_DESCRIPTION = { DtypeKind.FLOAT: (ColumnNullType.USE_NAN, None), - DtypeKind.DATETIME: (ColumnNullType.USE_SENTINEL, pd.NaT), + DtypeKind.DATETIME: (ColumnNullType.USE_SENTINEL, iNaT), DtypeKind.INT: (ColumnNullType.NON_NULLABLE, None), DtypeKind.UINT: (ColumnNullType.NON_NULLABLE, None), DtypeKind.BOOL: (ColumnNullType.NON_NULLABLE, None), diff --git a/pandas/tests/interchange/test_impl.py b/pandas/tests/interchange/test_impl.py index ada1b48d2b58d..0c2cffff8a159 100644 --- a/pandas/tests/interchange/test_impl.py +++ b/pandas/tests/interchange/test_impl.py @@ -4,6 +4,8 @@ import numpy as np import pytest +from pandas._libs.tslibs import iNaT + import pandas as pd import pandas._testing as tm from pandas.core.interchange.dataframe_protocol import ( @@ -185,4 +187,6 @@ def test_datetime(): assert col.size == 2 assert col.null_count == 1 assert col.dtype[0] == DtypeKind.DATETIME - assert col.describe_null == (ColumnNullType.USE_SENTINEL, pd.NaT) + assert col.describe_null == (ColumnNullType.USE_SENTINEL, iNaT) + + tm.assert_frame_equal(df, from_dataframe(df.__dataframe__()))