概要
pandas で日時や期間の情報を取得できる dt accessor の使い方を整理しました。
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 |
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
判定する関数
プロパティ | 意味 |
---|---|
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() で文字列に変換できます。
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
datetime → datetime.datetime
Series.dt.to_pydatetime() で datetime.datetime 型に変換できます。
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 の時刻にタイムゾーンを追加できます。
時刻のインデックスの変換は以下の関数でも可能です。
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() を使用します。
時刻のインデックスの変換は以下の関数でも可能です。
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
で指定します。
- pandas.Series.dt.floor(): 下に丸める
- pandas.Series.dt.ceil(): 上に丸める
- pandas.Series.dt.round(): 近いほうに丸める
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]
時間の情報を切り捨てる
日時の情報のみ必要で時間の情報が不要の場合は、pandas.Series.dt.normalize() で時間を 00:00 に設定できます。
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 |
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 で取得できます。
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
に変換できます。
print(s.dt.to_pytimedelta())
[datetime.timedelta(days=1, seconds=21901, microseconds=30)]
timedelta → 秒数
Series.dt.total_seconds() で timedelta を秒数換算した値を得られます。
print(s.dt.total_seconds())
0 108301.00003 dtype: float64
コメント