Warning: Undefined variable $position in /home/pystyles/pystyle.info/public_html/wp/wp-content/themes/lionblog/functions.php on line 4897

pandas – 日時や期間の情報を取得する dt accessor の使い方

pandas – 日時や期間の情報を取得する dt accessor の使い方

概要

pandas で日時や期間の情報を取得できる dt accessor の使い方を整理しました。

Advertisement

DatetimeProperties

datetime 型の Series の場合、DatetimeProperties を利用して、年、月といった日付の情報を取得することができます。 日付の情報を表す列でも型が datetime 型でなく、文字列になっている場合、まず pandas.to_datetime()datetime 型に変換してください。

s = pd.Series("20130101 09:10:12")
print(s.dt.year)
# AttributeError: Can only use .dt accessor with datetimelike values
s = pd.to_datetime(pd.Series("20130101 09:10:12"))
print(s.dt.year)

日時の一部の情報を取得する

プロパティ 意味 例 (2013-10-15 09:10:12+09:00)
Series.dt.date 日付 datetime.date 2013-10-15
Series.dt.time 時刻 (タイムゾーンなし) datetime.time 09:10:12
Series.dt.timetz 時刻 (タイムゾーンあり) datetime.time 09:10:12
Series.dt.year numpy.int64 2013
Series.dt.month numpy.int64 10
Series.dt.month_name() 月 (名前) str October
Series.dt.day numpy.int64 15
Series.dt.hour numpy.int64 9
Series.dt.minute numpy.int64 10
Series.dt.second numpy.int64 12
Series.dt.microsecond マイクロ秒 numpy.int64 0
Series.dt.nanosecond ナノ秒 numpy.int64 0
Series.dt.week 年の最初から数えて何周目か numpy.int64 42
Series.dt.weekofyear 年の最初から数えて何周目か numpy.int64 42
Series.dt.dayofyear 年の最初から数えて何日目か numpy.int64 288
Series.dt.dayofweek 週の最初から数えて何日目か numpy.int64 1
Series.dt.day_name() 曜日 str Tuesday
Series.dt.weekday 週の最初から数えて何日目か numpy.int64 1
Series.dt.quarter 四半期のうち、何半期目か numpy.int64 4
Series.dt.tz タイムゾーン pytz.tzfile.Asia/Tokyo Asia/Tokyo
In [1]:
import pandas as pd

s = pd.Series(pd.date_range("20131015 09:10:12", periods=1, tz="Asia/Tokyo"))

print(s)
print(s.dt.date)  # 日付
print(s.dt.time)  # 時間 (タイムゾーンなし)
print(s.dt.timetz)  # 時間 (タイムゾーンあり)
print(s.dt.year)  # 年
print(s.dt.month)  # 月
print(s.dt.day)  # 日
print(s.dt.hour)  # 時
print(s.dt.minute)  # 分
print(s.dt.second)  # 秒
print(s.dt.microsecond)  # マイクロ病
print(s.dt.nanosecond)  # ナノ病
print(s.dt.week)  # 年の最初から数えて何周目か
print(s.dt.dayofyear)  # 年の最初から数えて何日目か
print(s.dt.weekofyear)  # 年の最初から数えて何周目か
print(s.dt.dayofweek)  # 週の最初から数えて何日目か
print(s.dt.weekday)  # 週の最初から数えて何日目か
print(s.dt.quarter)  # 何半期か
print(s.dt.tz)  # タイムゾーン
0   2013-10-15 09:10:12+09:00
dtype: datetime64[ns, Asia/Tokyo]
0    2013-10-15
dtype: object
0    09:10:12
dtype: object
0    09:10:12
dtype: object
0    2013
dtype: int64
0    10
dtype: int64
0    15
dtype: int64
0    9
dtype: int64
0    10
dtype: int64
0    12
dtype: int64
0    0
dtype: int64
0    0
dtype: int64
0    42
dtype: int64
0    288
dtype: int64
0    42
dtype: int64
0    1
dtype: int64
0    1
dtype: int64
0    4
dtype: int64
Asia/Tokyo
<ipython-input-1-b18b5be2bff2>:17: FutureWarning: Series.dt.weekofyear and Series.dt.week have been deprecated. Please use Series.dt.isocalendar().week instead. print(s.dt.week) # 年の最初から数えて何周目か <ipython-input-1-b18b5be2bff2>:19: FutureWarning: Series.dt.weekofyear and Series.dt.week have been deprecated. Please use Series.dt.isocalendar().week instead. print(s.dt.weekofyear) # 年の最初から数えて何周目か

判定する関数

プロパティ 意味
Series.dt.is_month_start 月の最初の日かどうか
Series.dt.is_month_end 月の最後の日かどうか
Series.dt.is_quarter_start 四半期の最初の日かどうか
Series.dt.is_quarter_end 四半期の最後の日かどうか
Series.dt.is_year_start 年の最初の日かどうか
Series.dt.is_year_end 年の最後の日かどうか
Series.dt.is_leap_year うるう年かどうか

datetime → 文字列

Series.dt.strftime() で文字列に変換できます。

In [2]:
s = pd.to_datetime(pd.Series("2020-03-27 09:55:51.169633+09:00"))

print(s.dt.strftime("%Y年%m月%d日 %H:%M:%S"))
0    2020年03月27日 09:55:51
dtype: object
Advertisement

datetime → datetime.datetime

Series.dt.to_pydatetime() で datetime.datetime 型に変換できます。

In [3]:
s = pd.to_datetime(pd.Series("2020-03-27 09:55:51.169633+09:00"))

print(s.dt.to_pydatetime())
[datetime.datetime(2020, 3, 27, 9, 55, 51, 169633, tzinfo=pytz.FixedOffset(540))]

UTC -> ローカルタイム

Series.dt.tz_localize() で UTC の時刻にタイムゾーンを追加できます。

時刻のインデックスの変換は以下の関数でも可能です。

In [4]:
s = pd.to_datetime(pd.Series("2020-03-27 12:00:00"))

print(s.dt.tz_localize("Asia/Tokyo"))
0   2020-03-27 12:00:00+09:00
dtype: datetime64[ns, Asia/Tokyo]

タイムゾーン間の変換

Series.dt.tz_convert() ですでにタイムゾーン付きの時刻を別のタイムゾーンでの時刻に変換する場合は Series.dt.tz_convert() を使用します。

時刻のインデックスの変換は以下の関数でも可能です。

In [5]:
s = pd.to_datetime(pd.Series("2020-03-27 12:00:00+04:00"))

print(s.dt.tz_convert("Asia/Tokyo"))
0   2020-03-27 17:00:00+09:00
dtype: datetime64[ns, Asia/Tokyo]

日時を丸める

以下の関数で日時を丸めることができます。(例: 2020-01-01 12:02 → 2020-01-01 12:00) 丸める単位は引数 freq で指定します。

In [6]:
s = pd.to_datetime(pd.Series("2020-03-27 12:10:00"))

print(s)
# 1時間単位で切り下げ
print(s.dt.floor(freq="h"))
# 1時間単位で切り上げ
print(s.dt.ceil(freq="h"))
# 1時間単位で近い方に丸める
print(s.dt.round(freq="h"))
0   2020-03-27 12:10:00
dtype: datetime64[ns]
0   2020-03-27 12:00:00
dtype: datetime64[ns]
0   2020-03-27 13:00:00
dtype: datetime64[ns]
0   2020-03-27 12:00:00
dtype: datetime64[ns]
Advertisement

時間の情報を切り捨てる

日時の情報のみ必要で時間の情報が不要の場合は、pandas.Series.dt.normalize() で時間を 00:00 に設定できます。

In [7]:
s = pd.to_datetime(pd.Series("2020-03-27 12:10:00"))

print(s.dt.normalize())
0   2020-03-27
dtype: datetime64[ns]

TimedeltaProperties

timedelta 型の Series の場合、TimedeltaProperties を利用して、何日、何時間といった期間の情報を取得することができます。 日付の情報を表す列でも型が timedelta 型でなく、文字列になっている場合、まず pandas.to_timedelta()timedelta 型に変換してください。

s = pd.Series("1 days 06:05:01.00003")
print(s.dt.days)
# AttributeError: Can only use .dt accessor with datetimelike values
s = pd.to_timedelta(pd.Series("1 days 06:05:01.00003"))
print(s.dt.days)

期間の一部の情報を取得する

プロパティ 意味 例 (1 days 06:05:01.000030)
Series.dt.days numpy.int64 1
Series.dt.seconds numpy.int64 21901
Series.dt.microseconds マイクロ秒 numpy.int64 30
Series.dt.nanoseconds ナノ秒 numpy.int64 0
In [8]:
s = pd.to_timedelta(pd.Series("1 days 06:05:01.00003"))

print(s)
print(s.dt.days)  # 日
print(s.dt.seconds)  # 秒
print(s.dt.microseconds)  # マイクロ秒
print(s.dt.nanoseconds)  # ナノ秒
0   1 days 06:05:01.000030
dtype: timedelta64[ns]
0    1
dtype: int64
0    21901
dtype: int64
0    30
dtype: int64
0    0
dtype: int64

Series.dt.components で各単位の値を DataFrame で取得できます。

In [9]:
s = pd.to_timedelta(pd.Series("1 days 06:05:01.00003"))
s.dt.components
days hours minutes seconds milliseconds microseconds nanoseconds
0 1 6 5 1 0 30 0

timedelta → datetime.timedelta

Series.dt.to_pytimedelta()datetime.timedelta に変換できます。

In [10]:
print(s.dt.to_pytimedelta())
[datetime.timedelta(days=1, seconds=21901, microseconds=30)]
Advertisement

timedelta → 秒数

Series.dt.total_seconds() で timedelta を秒数換算した値を得られます。

In [11]:
print(s.dt.total_seconds())
0    108301.00003
dtype: float64