0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

`pandas.NaT.isoformat()`は文字列の`NaT`が返るが、`pandas.NaT.strftime()`は`ValueError`が発生する

Last updated at Posted at 2024-11-29

環境

  • Python 3.12.4
  • pandas 2.2.3

はじめに

dtypeがdatetime型であるSeriesを、文字列に変換したいです。
pandas.Series.applyで、pandas.Timestamp.isoformat()を実行して文字列に変換しました。

In [224]: import datetime

In [225]: import pandas as pd

In [224]: s = pd.Series([datetime.datetime.now(), None])



In [226]: s
Out[226]:
0   2024-11-29 09:11:47.236118
1                          NaT
dtype: datetime64[ns]

In [223]: s.apply(lambda e: e.isoformat(timespec="minutes"))
Out[223]:
0    2024-11-29T09:11
1                 NaT
dtype: object

途中で、ISO 8601形式でなく独自のフォーマットへ変換することになったので、pandas.Timestamp.strftime()を利用して文字列へ変換しようとしました。
しかし以下のValueErrorが発生しました。NaTに対してstrftimeは実行できないようです。

In [239]: s.apply(lambda e: e.strftime("%Y/%m/%d %H:%M"))
---------------------------------------------------------------------------
ValueError: NaTType does not support strftime

pd.NaTに対する挙動を確認する

pd.NaTに対してisoformat()を実行すると文字列のNaTが返ります。

In [227]: pd.NaT.isoformat()
Out[227]: 'NaT'

pd.NaTにはstrftimeメソッドは定義されています。しかし実行すると「サポートされていない」というエラーが発生します。

# `pd.NaT`に定義されているメソッドを確認する
In [240]: dir(pd.NaT)
Out[240]:
[
 ...
 'strftime',
 'strptime',
 ...
]

 
In [228]: pd.NaT.strftime("%Y")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[228], line 1
----> 1 pd.NaT.strftime("%Y")

File nattype.pyx:54, in pandas._libs.tslibs.nattype._make_error_func.f()

ValueError: NaTType does not support strftime

ソースコードを確認する

ValueError_make_error_func関数がraiseしています。

_libs/tslibs/nattype.pyx
def _make_error_func(func_name: str, cls):
    def f(*args, **kwargs):
        raise ValueError(f"NaTType does not support {func_name}")

    f.__name__ = func_name
    if isinstance(cls, str):
        # passed the literal docstring directly
        f.__doc__ = cls
    elif cls is not None:
        f.__doc__ = getattr(cls, func_name).__doc__
    return f

strftimeは、以下のように_make_error_func()の戻り値が設定されています。

_libs/tslibs/nattype.pyx
    strftime = _make_error_func(
        "strftime",
        """
        ...
        """,
    )

isoformatは以下のメソッドが定義されています。

_libs/tslibs/nattype.pyx
    def isoformat(self, sep: str = "T", timespec: str = "auto") -> str:
        # This allows Timestamp(ts.isoformat()) to always correctly roundtrip.
        return "NaT"

pandas.Series.dt.strftimeの結果

pandas.Series.dtisoformatは定義されていませんが、strftimeは定義されています。
pandas.Series.dt.strftimeを実行すれば、エラーなくNaTも変換できます。

In [246]: a = s.dt.strftime("%Y/%m/%d %H:%M")

In [251]: a
Out[251]:
0    2024/11/29 09:11
1                 NaN
dtype: object

In [253]: type(a[1])
Out[253]: float

なお、NaNは文字列ではなくfloat型です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?