はい、承知いたしました。PandasのTimestampに焦点を当てた、日付・時刻データの扱い方に関する詳細な記事を作成します。約5000語を目指し、コード例を豊富に盛り込みながら、基本的な使い方から応用、注意点までを網羅的に解説します。
以下に記事の内容を直接表示します。
PandasのTimestamp完全ガイド|日付・時刻データの扱い方
はじめに
データ分析の世界において、日付や時刻に関するデータ(時系列データ)は非常に一般的であり、その分析は多岐にわたります。商品の売上トレンド分析、株価の変動予測、サーバーのログ解析、気象データの分析など、多くのデータは時間的な要素を持っています。これらのデータを効果的に、そして正確に扱うことは、洞察を得る上で不可欠です。
Pythonでデータ分析を行う際、最も強力なライブラリの一つであるPandasは、日付・時刻データの扱いにも優れた機能を提供しています。Python標準ライブラリのdatetime
モジュールも強力ですが、Pandasはデータフレームやシリーズといった構造化データとの親和性が高く、ベクトル化された高速な処理、便利な機能(タイムゾーン、ビジネス日、頻度変換など)を提供します。
Pandasにおける日付・時刻データの中心的な型の一つがTimestamp
です。Timestamp
は、特定の瞬間(日付と時刻)を非常に高精度(ナノ秒まで)に表現するための型です。また、複数のTimestamp
を集めたものはDatetimeIndex
となり、Pandasのシリーズやデータフレームのインデックスとして非常によく利用されます。さらに、時間差を表現するTimedelta
、特定の期間(月、四半期、年など)と頻度を表現するPeriod
といった関連する型も存在します。
本記事では、これらのPandasの日付・時刻関連型のうち、Timestamp
に焦点を当てて、その基本的な使い方から、生成方法、豊富な属性、様々な操作、タイムゾーンの扱い、そして関連するTimedelta
やPeriod
との関係までを、詳細なコード例と共に徹底的に解説します。この記事を読むことで、あなたはPandasにおける日付・時刻データの扱いに自信を持ち、より高度な時系列分析に進むための確固たる基盤を築くことができるでしょう。
さあ、Pandas Timestamp
の世界に飛び込んでいきましょう!
1. Pandas Timestampの基本
Timestamp
は、Pandasで単一の時点(日付と時刻)を表すための基本的なデータ型です。これはPython標準ライブラリのdatetime.datetime
オブジェクトを拡張したものであり、Pandasのシリーズやデータフレーム内で効率的に日付・時刻データを扱うために設計されています。
なぜPandasは独自のTimestampを持つのか?
Pythonのdatetime.datetime
は非常に便利ですが、大量の日付・時刻データを扱う際にはいくつかの課題があります。
- パフォーマンス:
datetime
オブジェクトはスカラー値であり、配列(リストなど)に格納して操作しようとすると、Pythonのループ処理が必要になることが多く、非効率です。 - ベクトル化の欠如:
datetime
オブジェクトに対する操作(加算、減算、属性の抽出など)は、PandasのNumPyベースのベクトル化された演算の恩恵を受けにくいです。 - 機能の制限:
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()
: PandasTimestamp
オブジェクトを、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では、Timestamp
やDatetimeIndex
はタイムゾーン情報を持つことができます。タイムゾーン情報を持つものを「認識された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
.tz
がNone
であればナイーブ、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:00Localized 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:00Localized ambiguous time (infer): 2023-11-05 01:30:00-05:00
Localized ambiguous time (infer, single): 2023-11-05 01:30:00-05:00Localized 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
前述のように、Timestamp
とTimedelta
は密接に関連しています。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
“` -
Timestamp
とTimedelta
の演算: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
Timestamp
とTimedelta
を組み合わせることで、柔軟かつ正確な時間計算が可能になります。
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
やその他の日付・時刻データを扱う際に、知っておくべき注意点と推奨されるプラクティスがいくつかあります。
-
データ型の確認: 外部からデータを読み込んだ際、日付・時刻として解釈してほしい列が文字列型(
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)
“` -
文字列からの変換時のエラー処理:
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 のままになることに注意
“` -
パフォーマンス(特に大規模データ): 大量の文字列データを含む列を
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)
“`
-
タイムゾーンの統一: 異なるタイムゾーンのデータを扱う場合は、すべての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}”)
“` -
ナイーブと認識された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()
メソッドで相互変換できます。- データの読み込み後の型確認、変換時のエラー処理、大規模データでの
format
とcache
の使用、タイムゾーンの統一といったベストプラクティスは、効率的かつ正確なデータ分析のために重要です。
この記事で習得した知識は、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完全ガイド」の記事が完成しました。基本的な概念から生成、属性、操作、タイムゾーン、関連型、注意点、応用例までを網羅し、コード例も豊富に含めました。