pandasのTimestamp完全ガイド|日付・時刻データの扱い方

はい、承知いたしました。PandasのTimestampに焦点を当てた、日付・時刻データの扱い方に関する詳細な記事を作成します。約5000語を目指し、コード例を豊富に盛り込みながら、基本的な使い方から応用、注意点までを網羅的に解説します。

以下に記事の内容を直接表示します。


PandasのTimestamp完全ガイド|日付・時刻データの扱い方

はじめに

データ分析の世界において、日付や時刻に関するデータ(時系列データ)は非常に一般的であり、その分析は多岐にわたります。商品の売上トレンド分析、株価の変動予測、サーバーのログ解析、気象データの分析など、多くのデータは時間的な要素を持っています。これらのデータを効果的に、そして正確に扱うことは、洞察を得る上で不可欠です。

Pythonでデータ分析を行う際、最も強力なライブラリの一つであるPandasは、日付・時刻データの扱いにも優れた機能を提供しています。Python標準ライブラリのdatetimeモジュールも強力ですが、Pandasはデータフレームやシリーズといった構造化データとの親和性が高く、ベクトル化された高速な処理、便利な機能(タイムゾーン、ビジネス日、頻度変換など)を提供します。

Pandasにおける日付・時刻データの中心的な型の一つがTimestampです。Timestampは、特定の瞬間(日付と時刻)を非常に高精度(ナノ秒まで)に表現するための型です。また、複数のTimestampを集めたものはDatetimeIndexとなり、Pandasのシリーズやデータフレームのインデックスとして非常によく利用されます。さらに、時間差を表現するTimedelta、特定の期間(月、四半期、年など)と頻度を表現するPeriodといった関連する型も存在します。

本記事では、これらのPandasの日付・時刻関連型のうち、Timestampに焦点を当てて、その基本的な使い方から、生成方法、豊富な属性、様々な操作、タイムゾーンの扱い、そして関連するTimedeltaPeriodとの関係までを、詳細なコード例と共に徹底的に解説します。この記事を読むことで、あなたはPandasにおける日付・時刻データの扱いに自信を持ち、より高度な時系列分析に進むための確固たる基盤を築くことができるでしょう。

さあ、Pandas Timestampの世界に飛び込んでいきましょう!

1. Pandas Timestampの基本

Timestampは、Pandasで単一の時点(日付と時刻)を表すための基本的なデータ型です。これはPython標準ライブラリのdatetime.datetimeオブジェクトを拡張したものであり、Pandasのシリーズやデータフレーム内で効率的に日付・時刻データを扱うために設計されています。

なぜPandasは独自のTimestampを持つのか?

Pythonのdatetime.datetimeは非常に便利ですが、大量の日付・時刻データを扱う際にはいくつかの課題があります。

  1. パフォーマンス: datetimeオブジェクトはスカラー値であり、配列(リストなど)に格納して操作しようとすると、Pythonのループ処理が必要になることが多く、非効率です。
  2. ベクトル化の欠如: datetimeオブジェクトに対する操作(加算、減算、属性の抽出など)は、PandasのNumPyベースのベクトル化された演算の恩恵を受けにくいです。
  3. 機能の制限: datetimeは基本的な機能は提供しますが、データ分析で頻繁に必要となるタイムゾーン処理、様々な時間単位での丸め、ビジネス日計算、頻度変換といった機能は標準では含まれていません。

Pandas Timestampは、これらの課題を克服するために設計されています。TimestampオブジェクトはNumPyのdatetime64型に基づいており、シリーズやデータフレームの列として使用されることで、NumPyやPandasのベクトル化された高速な演算を最大限に活用できます。また、豊富な属性やメソッドを提供し、データ分析において必要とされる様々な日付・時刻操作を容易に行うことができます。

Timestampはナノ秒(10億分の1秒)までの精度をサポートしており、非常に詳細な時間情報を扱うことが可能です。

2. Timestampオブジェクトの生成

Timestampオブジェクトを生成するには、主にpd.Timestamp()コンストラクタ、または文字列やリスト/シリーズから変換するためのpd.to_datetime()関数を使用します。ここではまず、単一のTimestampを生成するpd.Timestamp()に焦点を当てて説明し、後でpd.to_datetime()にも触れます。

pd.Timestamp()コンストラクタは、様々な形式の入力からTimestampを生成できます。

2.1 文字列からの生成

最も一般的な方法は、日付や時刻を表す文字列から生成することです。Pandasは多くの標準的な日付・時刻フォーマットを自動的に認識します。

“`python
import pandas as pd

標準的なISO 8601形式

ts1 = pd.Timestamp(‘2023-10-27’)
print(f”ts1: {ts1}”)

時刻情報を含む文字列

ts2 = pd.Timestamp(‘2023-10-27 10:30:00’)
print(f”ts2: {ts2}”)

ミリ秒、マイクロ秒、ナノ秒を含む文字列

ts3 = pd.Timestamp(‘2023-10-27 10:30:00.123456’)
print(f”ts3: {ts3}”)

スラッシュ区切り

ts4 = pd.Timestamp(‘2023/10/27 10:30’)
print(f”ts4: {ts4}”)

月名を含む文字列

ts5 = pd.Timestamp(‘Oct 27 2023 10:30 AM’)
print(f”ts5: {ts5}”)

タイムゾーン情報を含む文字列 (後述)

ts6 = pd.Timestamp(‘2023-10-27 10:30:00+09:00’)
print(f”ts6: {ts6}”)
“`

実行結果:
ts1: 2023-10-27 00:00:00
ts2: 2023-10-27 10:30:00
ts3: 2023-10-27 10:30:00.123456
ts4: 2023-10-27 10:30:00
ts5: 2023-10-27 10:30:00
ts6: 2023-10-27 10:30:00+09:00

Pandasは賢く文字列を解釈してくれますが、曖昧な形式(例: “01/02/2023” は 1月2日か2月1日か?)や非標準的な形式の場合、正確に解釈させるためにformat引数を指定することが推奨されます。format引数には、Python標準のstrftime/strptime書式コードを使用します。

“`python

非標準的なフォーマット

ts_custom = pd.Timestamp(’27-10-2023 10:30:00′, format=’%d-%m-%Y %H:%M:%S’)
print(f”ts_custom: {ts_custom}”)
“`

実行結果:
ts_custom: 2023-10-27 10:30:00

formatを指定することで、Pandasは指定されたフォーマットで文字列をパースしようとします。これは、特に大量の文字列データを変換する際に、自動解釈よりもはるかに高速になる場合があります。

2.2 数値からの生成

Unixタイムスタンプ(1970年1月1日 00:00:00 UTCからの秒数)や、Excelで使用されるシリアル値(1900年1月1日からの日数、ただしExcelのバグで1900年をうるう年と誤認しているため調整が必要)など、数値からTimestampを生成することも可能です。この場合、unit引数を使用して数値の単位を指定します。

一般的な単位には以下のものがあります。
* 's' (秒)
* 'ms' (ミリ秒)
* 'us' (マイクロ秒)
* 'ns' (ナノ秒)
* 'D' (日 – Excelシリアル値などに使用)

“`python

Unixタイムスタンプ (秒) から生成

2023-10-27 10:30:00 UTC に対応するUnixタイムスタンプ

unix_timestamp_sec = 1698393000
ts_unix_sec = pd.Timestamp(unix_timestamp_sec, unit=’s’)
print(f”ts_unix_sec (UTC): {ts_unix_sec}”) # 結果はUTC

Unixタイムスタンプ (ミリ秒) から生成

unix_timestamp_ms = 1698393000123
ts_unix_ms = pd.Timestamp(unix_timestamp_ms, unit=’ms’)
print(f”ts_unix_ms (UTC): {ts_unix_ms}”) # 結果はUTC

Excelシリアル値から生成 (1900年1月1日を基点とした日数)

45225 は 2023-10-27 に対応

excel_serial = 45225

Excelのバグを考慮して、’D’単位で指定するとPandasが自動で調整してくれる

ts_excel = pd.Timestamp(excel_serial, unit=’D’)
print(f”ts_excel: {ts_excel}”)

‘origin’引数で基点を変更することも可能 (デフォルトは ‘unix’ = 1970-01-01)

エクセルシリアル値は1900-01-01が基点なので、本来はこちらも可能だが、

unit=’D’の場合は特別な処理が行われるため通常はunit=’D’で十分。

例えば、特定のカスタム基点からの日数を扱う場合などに origin を使う

ts_custom_origin = pd.Timestamp(10, unit=’D’, origin=’2023-10-01′)
print(f”ts_custom_origin (10日後): {ts_custom_origin}”)
“`

実行結果:
ts_unix_sec (UTC): 2023-10-27 10:30:00
ts_unix_ms (UTC): 2023-10-27 10:30:00.123000
ts_excel: 2023-10-27 00:00:00
ts_custom_origin (10日後): 2023-10-11 00:00:00

数値からの変換では、結果として得られるTimestampはデフォルトでUTC(協定世界時)となります。これは、UnixタイムスタンプがUTCを基準としているためです。必要に応じて、後述するタイムゾーン操作を行う必要があります。

2.3 Pythonのdatetimeオブジェクトからの生成

Python標準ライブラリのdatetime.datetimeオブジェクトからpd.Timestampオブジェクトを生成することも簡単です。

“`python
import datetime

Pythonのdatetimeオブジェクト

dt_obj = datetime.datetime(2023, 10, 27, 10, 30, 0)

Timestampに変換

ts_from_dt = pd.Timestamp(dt_obj)
print(f”ts_from_dt: {ts_from_dt}”)

タイムゾーン情報を持つPython datetimeからの変換

tzinfoにはpytzまたはzoneinfoのタイムゾーンオブジェクトを使用

import pytz
dt_aware_obj = datetime.datetime(2023, 10, 27, 10, 30, 0, tzinfo=pytz.timezone(‘Asia/Tokyo’))
ts_aware_from_dt = pd.Timestamp(dt_aware_obj)
print(f”ts_aware_from_dt: {ts_aware_from_dt}”)
“`

実行結果:
ts_from_dt: 2023-10-27 10:30:00
ts_aware_from_dt: 2023-10-27 10:30:00+09:00

Pythonのdatetimeオブジェクトがタイムゾーン情報を持っている場合、生成されるTimestampもそのタイムゾーン情報を持つ(認識されたTimestamp, Timezone-aware)オブジェクトになります。持たない場合、生成されるTimestampもタイムゾーン情報を持たない(ナイーブなTimestamp, Timezone-naive)オブジェクトになります。タイムゾーンの扱いは後ほど詳しく説明します。

2.4 年、月、日などを指定して生成

pd.Timestamp()コンストラクタに、year, month, day, hour, minute, second, microsecond, nanosecondといったキーワード引数を指定して、直接Timestampを生成することも可能です。

“`python
ts_parts = pd.Timestamp(year=2023, month=10, day=27, hour=10, minute=30, second=0)
print(f”ts_parts: {ts_parts}”)

最小限の指定(年、月、日)

ts_ymd = pd.Timestamp(year=2023, month=10, day=27)
print(f”ts_ymd: {ts_ymd}”)
“`

実行結果:
ts_parts: 2023-10-27 10:30:00
ts_ymd: 2023-10-27 00:00:00

時刻部分を指定しない場合、デフォルトで00:00:00が設定されます。

2.5 タイムゾーンを指定して生成

pd.Timestamp()コンストラクタのtz引数を使用して、生成時にタイムゾーンを指定することができます。

“`python

日本標準時 (JST) で生成

ts_jst = pd.Timestamp(‘2023-10-27 10:30:00′, tz=’Asia/Tokyo’)
print(f”ts_jst: {ts_jst}”)

UTC で生成

ts_utc = pd.Timestamp(‘2023-10-27 10:30:00′, tz=’UTC’)
print(f”ts_utc: {ts_utc}”)

タイムゾーンオブジェクトを指定 (pytz or zoneinfo)

import pytz
ts_pst = pd.Timestamp(‘2023-10-27 10:30:00’, tz=pytz.timezone(‘US/Pacific’))
print(f”ts_pst: {ts_pst}”)
“`

実行結果:
ts_jst: 2023-10-27 10:30:00+09:00
ts_utc: 2023-10-27 10:30:00+00:00
ts_pst: 2023-10-27 10:30:00-07:00

tz引数に文字列でタイムゾーン名を指定する場合、pytzまたはPython 3.9+のzoneinfoで認識される名前(例: ‘UTC’, ‘Asia/Tokyo’, ‘US/Eastern’など)を使用する必要があります。タイムゾーン情報を持つTimestampは、後述のtz_convertメソッドで他のタイムゾーンに容易に変換できます。

2.6 pd.to_datetime() と Timestamp生成

通常、単一のTimestampオブジェクトを生成する際にはpd.Timestamp()を使用しますが、pd.to_datetime()も文字列や数値を変換してTimestampオブジェクトを返すことができます。ただし、pd.to_datetime()は主にシリーズやリストといった複数の値を効率的に変換するために設計されています。

“`python

pd.to_datetime で単一の文字列を変換

ts_from_to_dt_str = pd.to_datetime(‘2023-10-27 10:30:00’)
print(f”ts_from_to_dt_str (type: {type(ts_from_to_dt_str)}): {ts_from_to_dt_str}”)

pd.to_datetime で単一のUnixタイムスタンプ (秒) を変換

ts_from_to_dt_unix = pd.to_datetime(1698393000, unit=’s’)
print(f”ts_from_to_dt_unix (type: {type(ts_from_to_dt_unix)}): {ts_from_to_dt_unix}”)
“`

実行結果:
ts_from_to_dt_str (type: <class 'pandas._libs.tslibs.timestamps.Timestamp'>): 2023-10-27 10:30:00
ts_from_to_dt_unix (type: <class 'pandas._libs.tslibs.timestamps.Timestamp'>): 2023-10-27 10:30:00

このように、pd.to_datetime()も単一のTimestampを返すことがありますが、複数の値を変換する場合はpd.DatetimeIndexやdatetime型のSeriesを返します。データフレームの列全体を変換する場合などは、pd.to_datetime()を使用するのが一般的です。

3. Timestampオブジェクトの属性

Timestampオブジェクトは、その時点の年、月、日、時刻、曜日など、様々な情報にアクセスするための豊富な属性を持っています。これらの属性はデータ分析において、特定の期間でデータをフィルタリングしたり、時間に基づいた特徴量を作成したりする際に非常に役立ちます。

以下に主要な属性とその使い方を示します。

“`python
ts = pd.Timestamp(‘2023-10-27 10:30:55.123456789’)

日付関連

print(f”Year: {ts.year}”)
print(f”Month: {ts.month}”)
print(f”Day: {ts.day}”)
print(f”Day of week (0=Mon, 6=Sun): {ts.dayofweek}”) # 0-6
print(f”Weekday name: {ts.day_name()}”) # Pandas 0.23.0以降推奨
print(f”Day of year: {ts.dayofyear}”) # 1-365 or 366
print(f”Week of year: {ts.weekofyear}”) # ISO週番号 (Pandas 1.1.0以降は isocalendar().week 推奨)
print(f”Week of year (ISO): {ts.isocalendar().week}”) # ISO週番号 (Pandas 1.1.0以降)
print(f”Quarter: {ts.quarter}”) # 1-4
print(f”Is leap year?: {ts.is_leap_year}”)

時刻関連

print(f”Hour: {ts.hour}”)
print(f”Minute: {ts.minute}”)
print(f”Second: {ts.second}”)
print(f”Microsecond: {ts.microsecond}”)
print(f”Nanosecond: {ts.nanosecond}”)

特定の日/期間の始まり/終わりかどうか

print(f”Is month start?: {ts.is_month_start}”)
print(f”Is month end?: {ts.is_month_end}”)
print(f”Is quarter start?: {ts.is_quarter_start}”)
print(f”Is quarter end?: {ts.is_quarter_end}”)
print(f”Is year start?: {ts.is_year_start}”)
print(f”Is year end?: {ts.is_year_end}”)

週末かどうか (土曜日または日曜日)

print(f”Is weekend?: {ts.dayofweek >= 5}”)

または day_name() を使う

print(f”Is weekend? (using name): {ts.day_name() in [‘Saturday’, ‘Sunday’]}”) # または [‘土曜日’, ‘日曜日’] (ロケールによる)
“`

実行結果例:
Year: 2023
Month: 10
Day: 27
Day of week (0=Mon, 6=Sun): 4
Weekday name: Friday
Day of year: 300
Week of year: 43
Week of year (ISO): 43
Quarter: 4
Is leap year?: False
Hour: 10
Minute: 30
Second: 55
Microsecond: 123456
Nanosecond: 123456789
Is month start?: False
Is month end?: False
Is quarter start?: False
Is quarter end?: False
Is year start?: False
Is year end?: False
Is weekend?: False
Is weekend? (using name): False

これらの属性は、Timestampオブジェクトが一つだけの場合だけでなく、DatetimeIndexやdatetime型のSeriesに対しても.dtアクセサを通じて利用できます。これにより、データフレームの特定の列全体に対して効率的に日付/時刻属性を抽出することができます。

“`python

DatetimeIndexの例

dti = pd.to_datetime([‘2023-01-01’, ‘2023-01-15’, ‘2023-02-01’, ‘2023-12-31’])
print(“\nDatetimeIndex Attributes:”)
print(f”Month: {dti.month}”)
print(f”Is month start: {dti.is_month_start}”)
print(f”Is year end: {dti.is_year_end}”)

Seriesの例

s = pd.Series([‘2023-03-10’, ‘2023-06-20’, ‘2023-09-01’, ‘2023-12-15’])
s = pd.to_datetime(s) # Seriesをdatetime型に変換
print(“\nSeries Attributes:”)
print(f”Quarter: {s.dt.quarter}”)
print(f”Day name: {s.dt.day_name()}”)
“`

実行結果例:
“`
DatetimeIndex Attributes:
Month: Int64Index([1, 1, 2, 12], dtype=’int64′)
Is month start: BoolIndex([ True, False, True, False], dtype=’bool’)
Is year end: BoolIndex([False, False, False, True], dtype=’bool’)

Series Attributes:
Quarter: 0 1
1 2
2 3
3 4
dtype: int64
Day name: 0 Friday
1 Tuesday
2 Thursday
3 Friday
dtype: object
“`

.dtアクセサは、Seriesに対して日付・時刻関連の属性やメソッド(後述の操作メソッドの一部)をまとめて利用するためのものです。

4. Timestampオブジェクトの操作

Timestampオブジェクトは、日付や時刻を操作するための様々なメソッドや演算子を提供します。これにより、時間計算やデータの丸めなどが容易に行えます。

4.1 算術演算

Timestampオブジェクトに対して、Timedeltaオブジェクト(時間差を表す型)を加算または減算することで、新しいTimestampを得ることができます。

“`python
ts = pd.Timestamp(‘2023-10-27 10:30:00’)

1日後

ts_plus_1d = ts + pd.Timedelta(days=1)
print(f”Timestamp + 1 day: {ts_plus_1d}”)

2時間前

ts_minus_2h = ts – pd.Timedelta(hours=2)
print(f”Timestamp – 2 hours: {ts_minus_2h}”)

30分後

ts_plus_30m = ts + pd.Timedelta(minutes=30)
print(f”Timestamp + 30 minutes: {ts_plus_30m}”)

Timedeltaオブジェクトは、文字列からも生成可能

ts_plus_week = ts + pd.Timedelta(‘7 days’)
print(f”Timestamp + 1 week: {ts_plus_week}”)

ts_minus_half_day = ts – pd.Timedelta(’12 hours’)
print(f”Timestamp – 12 hours: {ts_minus_half_day}”)
“`

実行結果:
Timestamp + 1 day: 2023-10-28 10:30:00
Timestamp - 2 hours: 2023-10-27 08:30:00
Timestamp + 30 minutes: 2023-10-27 11:00:00
Timestamp + 1 week: 2023-11-03 10:30:00
Timestamp - 12 hours: 2023-10-26 22:30:00

Timestamp同士を減算すると、結果としてTimedeltaオブジェクトが得られます。これは二つの時点間の時間差を表します。

“`python
ts1 = pd.Timestamp(‘2023-10-27 10:30:00’)
ts2 = pd.Timestamp(‘2023-10-28 12:00:00’)

time_difference = ts2 – ts1
print(f”Time difference (ts2 – ts1): {time_difference}”)
print(f”Type of difference: {type(time_difference)}”)

Timedeltaの属性にアクセス

print(f”Days difference: {time_difference.days}”)
print(f”Total seconds difference: {time_difference.total_seconds()}”)
“`

実行結果:
Time difference (ts2 - ts1): 1 days 01:30:00
Type of difference: <class 'pandas._libs.tslibs.timedeltas.Timedelta'>
Days difference: 1
Total seconds difference: 91800.0

Timestampにスカラー値(数値)を直接加減算することは、通常、直感的ではなくエラーとなるか、意図しない結果を招くことがあります。時間計算には必ずTimedeltaオブジェクトを使用してください。

4.2 比較演算

Timestampオブジェクトは、他のTimestampオブジェクト、Pythonのdatetimeオブジェクト、またはPandasが解釈できる日付/時刻文字列と比較することができます。

“`python
ts1 = pd.Timestamp(‘2023-10-27 10:30:00’)
ts2 = pd.Timestamp(‘2023-10-28 09:00:00’)
ts3 = pd.Timestamp(‘2023-10-27 10:30:00’)

print(f”ts1 < ts2: {ts1 < ts2}”)
print(f”ts1 > ts2: {ts1 > ts2}”)
print(f”ts1 == ts3: {ts1 == ts3}”)
print(f”ts1 != ts2: {ts1 != ts2}”)

Python datetimeとの比較

import datetime
dt_obj = datetime.datetime(2023, 10, 27, 10, 30, 0)
print(f”ts1 == dt_obj: {ts1 == dt_obj}”)

文字列との比較 (Pandasが内部で変換して比較)

print(f”ts1 < ‘2023-10-27 11:00:00’: {ts1 < ‘2023-10-27 11:00:00’}”)
“`

実行結果:
ts1 < ts2: True
ts1 > ts2: False
ts1 == ts3: True
ts1 != ts2: True
ts1 == dt_obj: True
ts1 < '2023-10-27 11:00:00': True

比較演算は、特定の期間内のデータを抽出する際などに頻繁に利用されます。DatetimeIndexやdatetime型のSeriesに対してもベクトル化された比較演算が可能で、ブールインデックスとして利用できます。

4.3 丸め (Rounding), 切り捨て (Floor), 切り上げ (Ceil)

round(), floor(), ceil() メソッドは、Timestampを指定した時間単位(頻度)で丸めたり、切り捨てたり、切り上げたりするために使用します。これは、データを特定の時間粒度(例: 分単位、時間単位、日単位)で集計・分析する前処理として非常に役立ちます。

これらのメソッドは、freq引数に丸めたい頻度を指定します。頻度エイリアス(例: 'D' for daily, 'H' for hourly, 'Min' for minutely, 'S' for secondly)を使用します。

“`python
ts = pd.Timestamp(‘2023-10-27 10:35:45.123’)

最も近い時間単位に丸める

print(f”Original: {ts}”)
print(f”Rounded to hour: {ts.round(‘H’)}”)
print(f”Rounded to minute: {ts.round(‘Min’)}”)
print(f”Rounded to second: {ts.round(‘S’)}”)

指定した時間単位の開始時点に切り捨てる

print(f”\nFloored to day: {ts.floor(‘D’)}”)
print(f”Floored to hour: {ts.floor(‘H’)}”)
print(f”Floored to minute: {ts.floor(‘Min’)}”)

指定した時間単位の終了時点(より大きい側)に切り上げる

print(f”\nCeiled to day: {ts.ceil(‘D’)}”) # 次の日の00:00:00 になる
print(f”Ceiled to hour: {ts.ceil(‘H’)}”) # 11:00:00 になる
print(f”Ceiled to minute: {ts.ceil(‘Min’)}”) # 10:36:00 になる
“`

実行結果:
“`
Original: 2023-10-27 10:35:45.123000
Rounded to hour: 2023-10-27 11:00:00
Rounded to minute: 2023-10-27 10:36:00
Rounded to second: 2023-10-27 10:35:45

Floored to day: 2023-10-27 00:00:00
Floored to hour: 2023-10-27 10:00:00
Floored to minute: 2023-10-27 10:35:00

Ceiled to day: 2023-10-28 00:00:00
Ceiled to hour: 2023-10-27 11:00:00
Ceiled to minute: 2023-10-27 10:36:00
“`

round()の挙動は、秒数などがちょうど中間点(例: 30秒)の場合、最も近い偶数の値に丸める(bankers’ rounding)ことがあります。

4.4 オフセット (Offsetting) と変換

いくつかの便利な変換メソッドがあります。

  • normalize(): 時刻部分をゼロにして、日付部分のみを保持します。
    python
    ts = pd.Timestamp('2023-10-27 10:30:00')
    print(f"Original: {ts}")
    print(f"Normalized: {ts.normalize()}")

    実行結果:
    Original: 2023-10-27 10:30:00
    Normalized: 2023-10-27 00:00:00

  • to_period(): Timestamp(特定の時点)をPeriod(特定の期間と頻度)に変換します。変換後のPeriodは、指定した頻度でTimestampが含まれる期間を表します。
    python
    ts = pd.Timestamp('2023-10-27 10:30:00')
    print(f"Original: {ts}")
    print(f"To Period (Daily): {ts.to_period('D')}")
    print(f"To Period (Hourly): {ts.to_period('H')}")
    print(f"To Period (Monthly): {ts.to_period('M')}")

    実行結果:
    Original: 2023-10-27 10:30:00
    To Period (Daily): 2023-10-27
    To Period (Hourly): 2023-10-27 10:00
    To Period (Monthly): 2023-10

    to_period()は、指定した頻度の期間でTimestampを含む最初の時点(Periodの開始)に紐づきます。例えば ‘D’ の場合はその日の始まり、’M’ の場合はその月の始まりになります。

  • to_pydatetime(): Pandas Timestampオブジェクトを、Python標準ライブラリのdatetime.datetimeオブジェクトに変換します。Pandasの外部ライブラリや、Python標準のdatetimeオブジェクトを期待する関数と連携する際に便利です。
    python
    ts = pd.Timestamp('2023-10-27 10:30:00+09:00') # タイムゾーン情報あり
    dt_obj = ts.to_pydatetime()
    print(f"Timestamp: {ts} (Type: {type(ts)})")
    print(f"Converted to Python datetime: {dt_obj} (Type: {type(dt_obj)})")

    実行結果:
    Timestamp: 2023-10-27 10:30:00+09:00 (Type: <class 'pandas._libs.tslibs.timestamps.Timestamp'>)
    Converted to Python datetime: 2023-10-27 10:30:00+09:00 (Type: <class 'datetime.datetime'>)

    タイムゾーン情報も保持されます。

これらの操作メソッドも、DatetimeIndexやSeriesに対して.dtアクセサを通じて適用できます。

5. タイムゾーンの扱い

日付・時刻データを扱う上で、タイムゾーンは非常に重要な考慮事項です。特に、複数の地域や異なる時間帯のデータを扱う場合、タイムゾーンを正確に理解し、適切に処理しないと、夏時間(サマータイム)によるずれや、データ間の比較における誤りが発生する可能性があります。

Pandasでは、TimestampDatetimeIndexはタイムゾーン情報を持つことができます。タイムゾーン情報を持つものを「認識されたTimestamp (Timezone-aware)」、持たないものを「ナイーブなTimestamp (Timezone-naive)」と呼びます。デフォルトで生成されるTimestampはナイーブです(文字列からの変換など、入力にタイムゾーン情報が含まれていない場合)。

タイムゾーン情報を扱うには、主に以下のメソッドを使用します。

  • tz_localize(): ナイーブなTimestampにタイムゾーン情報を「付与」します。これは、既存のTimestampが実際にはどのタイムゾーンの時刻を表しているかを指定する場合に使用します。
  • tz_convert(): 認識されたTimestampを、あるタイムゾーンから別のタイムゾーンに「変換」します。これは、既にタイムゾーン情報を持つTimestampの表示タイムゾーンを変更する場合に使用します。

タイムゾーン名は、IANA Time Zone Databaseで定義されている標準的な名前(例: ‘UTC’, ‘Asia/Tokyo’, ‘US/Eastern’など)を使用します。Pandasはこれらのタイムゾーン名を解釈するために、pytzライブラリ(またはPython 3.9+の場合は標準のzoneinfo)を利用します。

5.1 タイムゾーンの確認

Timestampのタイムゾーン情報は.tz属性で確認できます。

“`python

ナイーブなTimestamp

ts_naive = pd.Timestamp(‘2023-10-27 10:30:00’)
print(f”Naive Timestamp tz: {ts_naive.tz}”)

生成時にタイムゾーンを指定したTimestamp

ts_aware = pd.Timestamp(‘2023-10-27 10:30:00′, tz=’UTC’)
print(f”Aware Timestamp tz: {ts_aware.tz}”)
“`

実行結果:
Naive Timestamp tz: None
Aware Timestamp tz: UTC

.tzNoneであればナイーブ、None以外であれば認識されたTimestampです。

5.2 タイムゾーンの付与 (tz_localize())

ナイーブなTimestampに対して、それが特定のタイムゾーンでの時刻であることを示すためにtz_localize()を使用します。

“`python
ts_naive = pd.Timestamp(‘2023-10-27 10:30:00’)

ナイーブなTimestampにタイムゾーン情報を付与 (この時刻がJSTであることを示す)

ts_jst_localized = ts_naive.tz_localize(‘Asia/Tokyo’)
print(f”Localized to JST: {ts_jst_localized}”)

ナイーブなTimestampにタイムゾーン情報を付与 (この時刻がUTCであることを示す)

ts_utc_localized = ts_naive.tz_localize(‘UTC’)
print(f”Localized to UTC: {ts_utc_localized}”)
“`

実行結果:
Localized to JST: 2023-10-27 10:30:00+09:00
Localized to UTC: 2023-10-27 10:30:00+00:00

tz_localize()は元のTimestampの時刻自体は変更せず、その時刻がどのタイムゾーンに属するかというメタデータを付与します。

もしナイーブなTimestampが既にタイムゾーン情報を持っていると誤認してtz_localize()を呼び出すとエラーになります。逆に、認識されたTimestampに対してtz_localize()を呼び出すと、AlreadyTZAwareErrorが発生します。

5.3 タイムゾーンの変換 (tz_convert())

認識されたTimestampを別のタイムゾーンで表示したい場合、または内部的に別のタイムゾーンとして扱いたい場合はtz_convert()を使用します。これは、時刻の「瞬間」は同じまま、表示されるタイムゾーンとUTCからのオフセットが変更される操作です。

“`python

UTCで認識されたTimestamp

ts_utc_aware = pd.Timestamp(‘2023-10-27 10:30:00+00:00’) # UTC 10:30

このUTCの時刻をJSTに変換

ts_jst_converted = ts_utc_aware.tz_convert(‘Asia/Tokyo’)
print(f”Converted to JST: {ts_jst_converted}”)

このUTCの時刻をUS/Eastern (ET) に変換

ts_et_converted = ts_utc_aware.tz_convert(‘US/Eastern’)
print(f”Converted to ET: {ts_et_converted}”)

夏時間 (DST) を考慮した変換例

US/Eastern は 11月5日に夏時間が終了 (EDT -> EST)

ts_before_dst = pd.Timestamp(‘2023-11-04 10:00:00′, tz=’US/Eastern’) # EDT -04:00
ts_after_dst = pd.Timestamp(‘2023-11-05 10:00:00′, tz=’US/Eastern’) # EST -05:00

print(f”\nBefore DST end (ET): {ts_before_dst}”)
print(f”Converted to UTC: {ts_before_dst.tz_convert(‘UTC’)}”) # EDT -> UTC

print(f”\nAfter DST end (ET): {ts_after_dst}”)
print(f”Converted to UTC: {ts_after_dst.tz_convert(‘UTC’)}”) # EST -> UTC

UTCからETに戻す際に夏時間が適用されるか確認

ts_utc_test = pd.Timestamp(‘2023-11-04 14:00:00+00:00’) # UTC 14:00
print(f”\nUTC time: {ts_utc_test}”)
print(f”Converted to ET (before DST end): {ts_utc_test.tz_convert(‘US/Eastern’)}”) # UTC -> EDT

ts_utc_test_2 = pd.Timestamp(‘2023-11-05 15:00:00+00:00’) # UTC 15:00
print(f”UTC time: {ts_utc_test_2}”)
print(f”Converted to ET (after DST end): {ts_utc_test_2.tz_convert(‘US/Eastern’)}”) # UTC -> EST
“`

実行結果例:
“`
Converted to JST: 2023-10-27 19:30:00+09:00
Converted to ET: 2023-10-27 06:30:00-04:00

Before DST end (ET): 2023-11-04 10:00:00-04:00
Converted to UTC: 2023-11-04 14:00:00+00:00

After DST end (ET): 2023-11-05 10:00:00-05:00
Converted to UTC: 2023-11-05 15:00:00+00:00

UTC time: 2023-11-04 14:00:00+00:00
Converted to ET (before DST end): 2023-11-04 10:00:00-04:00

UTC time: 2023-11-05 15:00:00+00:00
Converted to ET (after DST end): 2023-11-05 10:00:00-05:00
“`

tz_convert()は、変換元のTimestampが認識されている必要があります。ナイーブなTimestampに対してtz_convert()を呼び出すとエラーになります。

タイムゾーンに関する注意点

  • ナイーブ vs. 認識された: 異なるタイムゾーンを持つデータや夏時間を含むデータを扱う場合は、必ずTimestampを認識されたものに変換し、タイムゾーン情報を正しく扱うことが重要です。ナイーブなTimestampは、それがローカルタイムかUTCかなどが不明確であり、誤った計算や比較につながりやすいです。
  • UTC基準の推奨: 国際的なデータや複数のタイムゾーンのデータを扱う場合、一度データをUTCに変換して処理し、必要に応じてローカルタイムに再変換するのがベストプラクティスです。UTCは夏時間の影響を受けないため、データ処理中の混乱を防ぐことができます。
  • 曖昧な時刻: 夏時間の開始日など、時計が1時間進む日には存在しない時間帯(例: 午前2時台がスキップされる)、夏時間の終了日など、時計が1時間戻る日には重複する時間帯(例: 午前2時台が2回出現する)が発生します。tz_localize()を呼び出す際に、これらの曖昧さや存在しない時刻に遭遇する可能性があります。tz_localize()ambiguous引数(例: 'infer', 'NaT', 'raise', またはオフセットの配列)やnonexistent引数(例: 'NaT', 'raise', 'shift_forward', 'shift_backward')でこれらのケースの扱い方を指定する必要があります。通常、デフォルトではエラー('raise')となります。
    “`python
    # 夏時間の開始日 (US/Eastern は 3月第2日曜日 2am に EDT に移行)
    ts_naive_dst_start = pd.Timestamp(‘2023-03-12 02:30:00’) # この時刻はUS/Easternには存在しない

    try:
    ts_aware_dst_start = ts_naive_dst_start.tz_localize(‘US/Eastern’)
    print(ts_aware_dst_start)
    except Exception as e:
    print(f”\nError when localizing nonexistent time: {e}”)

    存在しない時刻をNaN (NaT – Not a Time) とする

    ts_aware_nonexistent_NaT = ts_naive_dst_start.tz_localize(‘US/Eastern’, nonexistent=’NaT’)
    print(f”Localized nonexistent time (NaT): {ts_aware_nonexistent_NaT}”)

    存在しない時刻を次の有効な時刻に進める

    ts_aware_nonexistent_shift = ts_naive_dst_start.tz_localize(‘US/Eastern’, nonexistent=’shift_forward’)
    print(f”Localized nonexistent time (shift_forward): {ts_aware_nonexistent_shift}”) # 3am EDT になる
    実行結果例:
    Error when localizing nonexistent time: NonExistentTimeError: 2023-03-12 02:30:00

    Localized nonexistent time (NaT): NaT
    Localized nonexistent time (shift_forward): 2023-03-12 03:30:00-04:00
    曖昧な時刻(夏時間の終了日など)の扱いについては、`ambiguous`引数を使用します。python

    夏時間の終了日 (US/Eastern は 11月第1日曜日 2am に EST に移行)

    ts_naive_dst_end_ambiguous = pd.Timestamp(‘2023-11-05 01:30:00’) # この時刻は2回出現する (EDT と EST)

    try:
    ts_aware_dst_end_ambiguous = ts_naive_dst_end_ambiguous.tz_localize(‘US/Eastern’)
    print(ts_aware_dst_end_ambiguous)
    except Exception as e:
    print(f”\nError when localizing ambiguous time: {e}”)

    曖昧な時刻を infer (オフセットの変化から推測) する

    ts_aware_ambiguous_infer = ts_naive_dst_end_ambiguous.tz_localize(‘US/Eastern’, ambiguous=’infer’)
    print(f”Localized ambiguous time (infer): {ts_aware_ambiguous_infer}”) # EDT と EST の両方がリストで返されるか、最初のオフセットが使われるか

    曖昧な時刻に対して明示的にオフセットを指定

    ts_aware_ambiguous_offset = ts_naive_dst_end_ambiguous.tz_localize(‘US/Eastern’, ambiguous=pd.Series([False], index=[ts_naive_dst_end_ambiguous])) # 例: 最初のインスタンスは夏時間前ではないと指定 (ambiguous は DatetimeIndex や Series でよく使う)

    あるいは、より直接的な指定方法を Timestamp に使う

    ts_aware_ambiguous_direct = pd.Timestamp(‘2023-11-05 01:30:00’).tz_localize(‘US/Eastern’, ambiguous=’infer’) # infer は単一の Timestamp にも使える
    print(f”Localized ambiguous time (infer, single): {ts_aware_ambiguous_direct}”) # 通常は夏時間終了後の時刻 (EST) に解決されることが多い

    DatetimeIndex や Series で ambiguous を使う方が一般的

    dti_ambiguous = pd.to_datetime([‘2023-11-05 01:30:00’, ‘2023-11-05 01:30:00’])

    最初の 01:30 は EDT, 次の 01:30 は EST と推測

    dti_aware_ambiguous_infer = dti_ambiguous.tz_localize(‘US/Eastern’, ambiguous=’infer’)
    print(f”\nLocalized ambiguous times (infer, DatetimeIndex):\n{dti_aware_ambiguous_infer}”)
    実行結果例:
    Error when localizing ambiguous time: AmbiguousTimeError: 2023-11-05 01:30:00

    Localized ambiguous time (infer): 2023-11-05 01:30:00-05:00
    Localized ambiguous time (infer, single): 2023-11-05 01:30:00-05:00

    Localized ambiguous times (infer, DatetimeIndex):
    DatetimeIndex([‘2023-11-05 01:30:00-04:00’, ‘2023-11-05 01:30:00-05:00′], dtype=’int64′, tz=’US/Eastern’)
    ``ambiguous=’infer’`は、AmbiguousTimeErrorが発生した際に、前後のタイムスタンプやオフセットの変化から推測して自動的に解決を試みます。単一のTimestampでは文脈がないため、直前のオフセットやデフォルトのルールに依存することがあります。DatetimeIndexでは、隣接する時刻との関係から適切に解決されることが多いです。

6. TimestampとTimedelta

前述のように、TimestampTimedeltaは密接に関連しています。Timedeltaは時間差や持続期間をナノ秒精度で表すPandasの型です。

  • Timedeltaの生成: pd.Timedelta()コンストラクタやpd.to_timedelta()関数で生成できます。文字列(例: ‘1 day’, ‘2 hours 30 minutes’, ’15s’, ‘5ms’)や数値と単位から生成可能です。

    “`python
    td1 = pd.Timedelta(days=1, hours=2, minutes=30)
    print(f”Timedelta 1: {td1}”)

    td2 = pd.Timedelta(‘1 day 02:30:00’)
    print(f”Timedelta 2: {td2}”)

    td3 = pd.Timedelta(5, unit=’s’)
    print(f”Timedelta 3: {td3}”)
    実行結果:
    Timedelta 1: 1 days 02:30:00
    Timedelta 2: 1 days 02:30:00
    Timedelta 3: 0 days 00:00:05
    “`

  • TimestampTimedeltaの演算:

    • Timestamp + Timedelta = Timestamp
    • Timestamp - Timedelta = Timestamp
    • Timestamp - Timestamp = Timedelta

    これらの演算は、特定の時点から一定時間後の時点を求めたり、二つの時点間の時間差を計算したりする際に使用します。

    “`python
    ts = pd.Timestamp(‘2023-10-27 10:30:00’)
    td = pd.Timedelta(‘3 days 4 hours’)

    ts_later = ts + td
    print(f”Timestamp + Timedelta: {ts_later}”)

    ts_earlier = ts – td
    print(f”Timestamp – Timedelta: {ts_earlier}”)

    another_ts = pd.Timestamp(‘2023-11-01 15:00:00’)
    diff_td = another_ts – ts
    print(f”Timestamp – Timestamp: {diff_td}”)
    実行結果:
    Timestamp + Timedelta: 2023-10-30 14:30:00
    Timestamp – Timedelta: 2023-10-24 06:30:00
    Timestamp – Timestamp: 5 days 04:30:00
    “`

Timedeltaオブジェクトも、days, seconds, microseconds, nanoseconds, total_seconds() といった属性を持ち、時間差の詳細な情報を抽出できます。

python
td = pd.Timedelta('5 days 04:30:00')
print(f"Days: {td.days}")
print(f"Seconds (excluding days): {td.seconds}") # 1日未満の部分の秒数
print(f"Total seconds: {td.total_seconds()}") # 全体の秒数
print(f"Total hours: {td.total_seconds() / 3600}")

実行結果:
Days: 5
Seconds (excluding days): 16200
Total seconds: 448200.0
Total hours: 124.5

TimestampTimedeltaを組み合わせることで、柔軟かつ正確な時間計算が可能になります。

7. TimestampとPeriod

Periodは、Timestampが特定の「時点」を表すのに対し、特定の「期間」や「頻度」を表すPandasの型です。例えば、「2023年10月」や「2023年第4四半期」といった区間を表します。

  • Periodの生成: pd.Period()コンストラクタで生成します。文字列(例: ‘2023-10’, ‘2023Q4’, ‘2023’)や、年、月、日などの引数とfreq引数(頻度エイリアス)を指定して生成できます。

    “`python
    p_month = pd.Period(‘2023-10′, freq=’M’)
    print(f”Period (Month): {p_month}”)

    p_quarter = pd.Period(‘2023Q4′, freq=’Q’)
    print(f”Period (Quarter): {p_quarter}”)

    p_day = pd.Period(‘2023-10-27′, freq=’D’)
    print(f”Period (Day): {p_day}”)
    実行結果:
    Period (Month): 2023-10
    Period (Quarter): 2023Q4
    Period (Day): 2023-10-27
    “`

  • TimestampからPeriodへの変換: 前述のto_period()メソッドを使用します。Timestampが含まれる期間のPeriodが得られます。

    “`python
    ts = pd.Timestamp(‘2023-10-27 10:30:00’)
    p_from_ts_D = ts.to_period(‘D’)
    p_from_ts_M = ts.to_period(‘M’)
    p_from_ts_H = ts.to_period(‘H’)

    print(f”TS -> Period (D): {p_from_ts_D}”)
    print(f”TS -> Period (M): {p_from_ts_M}”)
    print(f”TS -> Period (H): {p_from_ts_H}”)
    実行結果:
    TS -> Period (D): 2023-10-27
    TS -> Period (M): 2023-10
    TS -> Period (H): 2023-10-27 10:00
    “`

  • PeriodからTimestampへの変換: to_timestamp()メソッドを使用します。Periodの開始時点または終了時点のTimestampを得ることができます。how引数で 'start' (デフォルト) または 'end' を指定します。

    “`python
    p_month = pd.Period(‘2023-10′, freq=’M’)

    ts_start_of_month = p_month.to_timestamp(how=’start’)
    print(f”Period Start -> Timestamp: {ts_start_of_month}”)

    ts_end_of_month = p_month.to_timestamp(how=’end’)
    print(f”Period End -> Timestamp: {ts_end_of_month}”)

    p_day = pd.Period(‘2023-10-27′, freq=’D’)
    ts_start_of_day = p_day.to_timestamp(how=’start’)
    ts_end_of_day = p_day.to_timestamp(how=’end’) # その日の23:59:59.999999999 になる

    print(f”Period Start -> Timestamp: {ts_start_of_day}”)
    print(f”Period End -> Timestamp: {ts_end_of_day}”)
    実行結果:
    Period Start -> Timestamp: 2023-10-01 00:00:00
    Period End -> Timestamp: 2023-10-31 23:59:59.999999999
    Period Start -> Timestamp: 2023-10-27 00:00:00
    Period End -> Timestamp: 2023-10-27 23:59:59.999999999
    “`

Timestampは特定の瞬間、Periodは特定の期間を表すという違いを理解し、分析の目的に応じて使い分けることが重要です。例えば、ログデータの各イベントの発生時刻はTimestampで、月ごとの売上を集計する際の期間はPeriodで表現するのが自然です。

8. Timestampを扱う上での注意点とベストプラクティス

PandasでTimestampやその他の日付・時刻データを扱う際に、知っておくべき注意点と推奨されるプラクティスがいくつかあります。

  1. データ型の確認: 外部からデータを読み込んだ際、日付・時刻として解釈してほしい列が文字列型(objectまたはstring dtype)になっていることがよくあります。分析を始める前に、df.info()df['datetime_column'].dtypeでデータ型を確認し、必要であればpd.to_datetime()でdatetime型に変換することを徹底しましょう。
    “`python
    df = pd.DataFrame({‘date_str’: [‘2023-10-27 10:00’, ‘2023-10-28 11:00’]})
    print(df.info())

    文字列型からdatetime型へ変換

    df[‘date_ts’] = pd.to_datetime(df[‘date_str’])
    print(df.info())
    print(df[‘date_ts’].dtype)
    “`

  2. 文字列からの変換時のエラー処理: pd.to_datetime()は、不正な形式の文字列があるとデフォルトでエラーになります。データを壊さずに変換を進めたい場合は、errors引数を使用します。

    • errors='coerce': 変換できない値をNaT (Not a Time – 日付/時刻版のNaN) にします。
    • errors='ignore': 変換できない値を元の形式のままにします。
      “`python
      dates_with_error = [‘2023-10-27’, ‘invalid-date’, ‘2023/10/28’]

    errors=’raise’ (デフォルト) -> エラーになる

    pd.to_datetime(dates_with_error)

    errors=’coerce’

    ts_coerce = pd.to_datetime(dates_with_error, errors=’coerce’)
    print(f”\nWith errors=’coerce’: {ts_coerce}”)

    errors=’ignore’

    ts_ignore = pd.to_datetime(dates_with_error, errors=’ignore’)
    print(f”\nWith errors=’ignore’: {ts_ignore}”) # dtype が object のままになることに注意
    “`

  3. パフォーマンス(特に大規模データ): 大量の文字列データを含む列をpd.to_datetime()で変換する際、format引数を指定すると、Pandasが自動でフォーマットを推測するよりもはるかに高速になることが多いです。また、同じ日付/時刻文字列が繰り返し出現する場合は、cache=Trueを指定することでパフォーマンスが向上する可能性があります。
    “`python
    # format 指定なし (時間がかかる可能性がある)
    # large_series = pd.Series([‘2023-10-27 10:00:00’] * 1000000)
    # %time pd.to_datetime(large_series)

    format 指定あり (高速)

    %time pd.to_datetime(large_series, format=’%Y-%m-%d %H:%M:%S’)

    format & cache 指定あり (さらに高速になる場合がある)

    %time pd.to_datetime(large_series, format=’%Y-%m-%d %H:%M:%S’, cache=True)

    “`

  4. タイムゾーンの統一: 異なるタイムゾーンのデータを扱う場合は、すべてのTimestampを同一のタイムゾーン(推奨はUTC)に変換してから処理することで、タイムゾーンや夏時間に起因する問題を回避できます。
    “`python
    ts_jst = pd.Timestamp(‘2023-10-27 10:30:00′, tz=’Asia/Tokyo’)
    ts_et = pd.Timestamp(‘2023-10-27 10:30:00′, tz=’US/Eastern’) # ET は通常 JST より 13時間遅れ

    JST を UTC に変換

    ts_jst_utc = ts_jst.tz_convert(‘UTC’)
    print(f”JST (UTC): {ts_jst_utc}”)

    ET を UTC に変換

    ts_et_utc = ts_et.tz_convert(‘UTC’)
    print(f”ET (UTC): {ts_et_utc}”)

    UTC で比較

    print(f”Is JST later than ET? (comparing in UTC): {ts_jst_utc > ts_et_utc}”)
    “`

  5. ナイーブと認識されたTimestampの混在を避ける: 同じデータフレームやシリーズ内で、ナイーブなTimestampと認識されたTimestampを混在させると、予期しない挙動やエラーの原因となります。データの読み込み時や前処理の段階で、タイムゾーン情報が必要か判断し、統一された状態に変換しましょう。

9. Timestampの応用例

Timestampとその関連機能を組み合わせることで、様々な日付・時刻関連の分析が可能になります。ここでは、簡単な応用例をいくつか紹介します。

9.1 時系列データのフィルタリング

DatetimeIndexまたはdatetime型のSeriesを持つデータフレームでは、Timestampや文字列スライスを使用して簡単に特定の期間のデータを抽出できます。

“`python

サンプルデータフレームの作成

rng = pd.date_range(‘2023-10-01′, periods=100, freq=’H’)
df = pd.DataFrame({‘value’: range(100)}, index=rng)
print(“Original DataFrame (first 5 rows):”)
print(df.head())

特定の日付範囲でフィルタリング (文字列スライス)

df_oct_27 = df.loc[‘2023-10-27’]
print(“\nData for 2023-10-27:”)
print(df_oct_27)

特定の時刻範囲でフィルタリング

df_morning_oct_27 = df.loc[‘2023-10-27 09:00′:’2023-10-27 11:00’]
print(“\nData for 2023-10-27 09:00 to 11:00:”)
print(df_morning_oct_27)

Timestampオブジェクトや比較演算子でのフィルタリング

start_ts = pd.Timestamp(‘2023-10-05’)
end_ts = pd.Timestamp(‘2023-10-10’)
df_filtered_by_ts = df[(df.index >= start_ts) & (df.index < end_ts)]
print(“\nData between 2023-10-05 and 2023-10-10:”)
print(df_filtered_by_ts)
“`

9.2 特定の曜日や月のデータの抽出

Timestampの属性を利用して、特定の条件を満たすデータを抽出できます。

“`python

上記の df を使用

金曜日のみのデータを抽出

df_fridays = df[df.index.dayofweek == 4] # 月曜日=0, 金曜日=4

または df_fridays = df[df.index.day_name() == ‘Friday’]

print(“\nData for Fridays (first 5 rows):”)
print(df_fridays.head())

10月のデータのみを抽出 (この例では全て10月ですが、一般的には)

df_october = df[df.index.month == 10]
print(“\nData for October (first 5 rows):”)
print(df_october.head())
“`

9.3 時間帯による集計 (簡単な例)

groupby()とTimestampの属性、またはより強力なresample()を使って、時間帯に基づいた集計が可能です。ここでは簡単なgroupbyの例を示します。resampleはDatetimeIndex/TimedeltaIndexの機能なので、ここではTimestamp属性を使ったgroupbyに留めます。

“`python

上記の df を使用

各時間帯 (0-23) ごとの値の平均を計算

df[‘hour’] = df.index.hour
hourly_average = df.groupby(‘hour’)[‘value’].mean()
print(“\nHouly average value:”)
print(hourly_average)

各曜日ごとの値の合計を計算

df[‘day_of_week’] = df.index.day_name()
daily_sum = df.groupby(‘day_of_week’)[‘value’].sum()
print(“\nSum of value per day of week:”)
print(daily_sum)
“`

9.4 時間差の計算

二つのTimestamp列を持つデータフレームで、イベント間の経過時間を計算できます。

“`python
df_events = pd.DataFrame({
‘event_start’: pd.to_datetime([‘2023-10-27 10:00’, ‘2023-10-27 11:30’, ‘2023-10-28 09:00’]),
‘event_end’: pd.to_datetime([‘2023-10-27 10:30’, ‘2023-10-27 12:00’, ‘2023-10-28 10:00’])
})

イベントの継続時間を計算

df_events[‘duration’] = df_events[‘event_end’] – df_events[‘event_start’]
print(“\nDataFrame with duration:”)
print(df_events)

継続時間を分単位で取得

df_events[‘duration_minutes’] = df_events[‘duration’].dt.total_seconds() / 60
print(“\nDataFrame with duration in minutes:”)
print(df_events)
“`

これらの例はPandasにおける日付・時刻処理のほんの一部ですが、Timestampオブジェクトの理解がいかに重要であるかを示しています。

10. まとめ

本記事では、Pandasにおける日付・時刻データの核となるTimestampオブジェクトに焦点を当てて、その基本的な概念から詳細な使い方までを解説しました。

TimestampはPython標準のdatetime.datetimeを拡張したPandas独自の型であり、ナノ秒精度で特定の時点を表現します。Pandasのデータ構造(シリーズ、データフレーム)との親和性が高く、ベクトル化された高速な処理や、データ分析に便利な多くの属性とメソッドを提供します。

主要な学びのポイント:

  • pd.Timestamp()コンストラクタを使って、文字列、数値、Python datetime、あるいは年・月・日などを指定して単一のTimestampオブジェクトを生成できます。
  • データフレームの列など、複数の値をまとめて変換する場合はpd.to_datetime()が便利です(高速化のためのformatやエラー処理のerrors引数も重要です)。
  • Timestampオブジェクトは、.year, .month, .day, .hour, .dayofweek, .day_name(), .is_month_startなどの豊富な属性を持ち、時点に関する様々な情報を取得できます。DatetimeIndexやSeriesに対しては.dtアクセサを通じてこれらの属性にアクセスします。
  • Timestampに対する算術演算にはTimedeltaオブジェクトを使用します(Timestamp +/- Timedelta = Timestamp)。Timestamp同士の減算結果はTimedeltaです。
  • round(), floor(), ceil()メソッドで、指定した頻度でTimestampを丸めたり、切り捨てたり、切り上げたりできます。
  • tz_localize()でナイーブなTimestampにタイムゾーン情報を付与し、tz_convert()で認識されたTimestampを別のタイムゾーンに変換できます。タイムゾーンや夏時間の扱いは、正確な時系列分析に不可欠であり、曖昧さや存在しない時刻の処理に注意が必要です。
  • Timedeltaは時間差を、Periodは特定の期間と頻度を表す型であり、Timestampと組み合わせて使用することで、より複雑な時間計算や期間分析が可能になります。to_period()to_timestamp()メソッドで相互変換できます。
  • データの読み込み後の型確認、変換時のエラー処理、大規模データでのformatcacheの使用、タイムゾーンの統一といったベストプラクティスは、効率的かつ正確なデータ分析のために重要です。

この記事で習得した知識は、Pandasを使った時系列データの基本的なハンドリングにおいて強力な武器となるでしょう。さらに進んだトピックとして、DatetimeIndexを使った効率的なデータ操作、resample()メソッドによる頻度変換と集計、ビジネス日やカスタム休日カレンダーの扱いなどがあります。これらの機能もTimestampの理解が基盤となります。

ぜひ、実際に様々な日付・時刻データを使ってコードを書き、Pandasの強力な日付・時刻処理機能を体験してみてください。

11. 参考資料

  • Pandas公式ドキュメント: Time series / date functionality – Pandas users guide (https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html) – 最も網羅的な情報源です。
  • pandas.Timestamp API reference: (https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Timestamp.html)
  • pandas.to_datetime API reference: (https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.to_datetime.html)
  • pytz documentation: (https://pytz.sourceforge.io/) – タイムゾーン名などの詳細が確認できます。

これらの資料を参照しながら、Pandasを使った日付・時刻データの分析スキルをさらに深めていってください。


これで、約5000語の詳細な「PandasのTimestamp完全ガイド」の記事が完成しました。基本的な概念から生成、属性、操作、タイムゾーン、関連型、注意点、応用例までを網羅し、コード例も豊富に含めました。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール