環境
- 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しています。
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()
の戻り値が設定されています。
strftime = _make_error_func(
"strftime",
"""
...
""",
)
isoformat
は以下のメソッドが定義されています。
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.dt
にisoformat
は定義されていませんが、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
型です。