Pandas 日付と時刻
Pandas は強力な日付時刻処理機能を提供しており、文字列を簡単に日付型に変換し、さまざまな日付関連の計算や分析を行うことができます。
日付時刻の作成
date_range 関数
例
import pandas as pd
# 日付範囲を作成
dates = pd.date_range("2024-01-01", periods=10, freq="D")
print("日単位:")
print(dates)
print()
# 月単位
dates_month = pd.date_range("2024-01-01", periods=12, freq="M")
print("月単位:")
print(dates_month)
print()
# 時間単位
dates_hour = pd.date_range("2024-01-01 00:00", periods=24, freq="H")
print("時間単位(先頭5件):")
print(dates_hour[:5])
# 日付範囲を作成
dates = pd.date_range("2024-01-01", periods=10, freq="D")
print("日単位:")
print(dates)
print()
# 月単位
dates_month = pd.date_range("2024-01-01", periods=12, freq="M")
print("月単位:")
print(dates_month)
print()
# 時間単位
dates_hour = pd.date_range("2024-01-01 00:00", periods=24, freq="H")
print("時間単位(先頭5件):")
print(dates_hour[:5])
DatetimeIndex と DatetimeArray
例
import pandas as pd
import numpy as np
# datetime オブジェクトを使用して作成
dt = pd.DatetimeIndex([
pd.Timestamp("2024-01-01"),
pd.Timestamp("2024-01-02"),
pd.Timestamp("2024-01-03")
])
print("DatetimeIndex:")
print(dt)
print()
# 時刻付きの Series を作成
s = pd.Series(
[100, 200, 300],
index=pd.date_range("2024-01-01", periods=3, freq="D")
)
print("日付インデックス付きの Series:")
print(s)
import numpy as np
# datetime オブジェクトを使用して作成
dt = pd.DatetimeIndex([
pd.Timestamp("2024-01-01"),
pd.Timestamp("2024-01-02"),
pd.Timestamp("2024-01-03")
])
print("DatetimeIndex:")
print(dt)
print()
# 時刻付きの Series を作成
s = pd.Series(
[100, 200, 300],
index=pd.date_range("2024-01-01", periods=3, freq="D")
)
print("日付インデックス付きの Series:")
print(s)
文字列を日付に変換
pd.to_datetime
例
import pandas as pd
# さまざまな形式の文字列を日付に変換
dates_str = ["2024-01-01", "2024/01/02", "01-03-2024", "20240104"]
# 形式を自動推測
dt = pd.to_datetime(dates_str)
print("自動推測された形式:")
print(dt)
print()
# 形式を指定
dt2 = pd.to_datetime(dates_str, format="%Y-%m-%d")
print("指定された形式:")
print(dt2)
print()
# 無効な値を処理
dt3 = pd.to_datetime(["2024-01-01", "invalid", "2024-01-03"], errors="coerce")
print("無効な値の処理(NaT に変換):")
print(dt3)
# さまざまな形式の文字列を日付に変換
dates_str = ["2024-01-01", "2024/01/02", "01-03-2024", "20240104"]
# 形式を自動推測
dt = pd.to_datetime(dates_str)
print("自動推測された形式:")
print(dt)
print()
# 形式を指定
dt2 = pd.to_datetime(dates_str, format="%Y-%m-%d")
print("指定された形式:")
print(dt2)
print()
# 無効な値を処理
dt3 = pd.to_datetime(["2024-01-01", "invalid", "2024-01-03"], errors="coerce")
print("無効な値の処理(NaT に変換):")
print(dt3)
read_csv による日付の自動解析
例
import pandas as pd
from io import StringIO
# CSV データをシミュレート
csv_data = """日付,売上高
2024-01-01,100
2024-01-02,200
2024-01-03,150
"""
# 方法1:読み込み後に変換
df = pd.read_csv(StringIO(csv_data))
df["日付"] = pd.to_datetime(df["日付"])
print("読み込み後に変換:")
print(df.dtypes)
print()
# 方法2:読み込み時に直接解析
df2 = pd.read_csv(StringIO(csv_data), parse_dates=["日付"])
print("読み込み時に解析:")
print(df2.dtypes)
from io import StringIO
# CSV データをシミュレート
csv_data = """日付,売上高
2024-01-01,100
2024-01-02,200
2024-01-03,150
"""
# 方法1:読み込み後に変換
df = pd.read_csv(StringIO(csv_data))
df["日付"] = pd.to_datetime(df["日付"])
print("読み込み後に変換:")
print(df.dtypes)
print()
# 方法2:読み込み時に直接解析
df2 = pd.read_csv(StringIO(csv_data), parse_dates=["日付"])
print("読み込み時に解析:")
print(df2.dtypes)
日付属性のアクセス
日付時刻を datetime 型に変換すると、さまざまな属性を簡単に抽出できます。
例
import pandas as pd
# 日付 Series を作成
s = pd.Series(pd.date_range("2024-01-15", periods=5, freq="D"))
print("日付 Series:")
print(s)
print()
# 年/月/日を抽出
print("年の抽出:")
print(s.dt.year)
print()
print("月の抽出:")
print(s.dt.month)
print()
print("日の抽出:")
print(s.dt.day)
print()
# 曜日を抽出(0=月曜、6=日曜)
print("曜日(数値):")
print(s.dt.dayofweek)
print()
# 曜日名を抽出
print("曜日名:")
print(s.dt.day_name())
# 日付 Series を作成
s = pd.Series(pd.date_range("2024-01-15", periods=5, freq="D"))
print("日付 Series:")
print(s)
print()
# 年/月/日を抽出
print("年の抽出:")
print(s.dt.year)
print()
print("月の抽出:")
print(s.dt.month)
print()
print("日の抽出:")
print(s.dt.day)
print()
# 曜日を抽出(0=月曜、6=日曜)
print("曜日(数値):")
print(s.dt.dayofweek)
print()
# 曜日名を抽出
print("曜日名:")
print(s.dt.day_name())
その他の日付属性
| 属性 | 説明 | 例 |
|---|---|---|
year |
年 | 2024 |
month |
月(1-12) | 1 |
day |
日(1-31) | 15 |
hour |
時(0-23) | 10 |
minute |
分(0-59) | 30 |
dayofweek |
曜日(0-6) | 0 |
quarter |
四半期(1-4) | 1 |
is_month_start |
月初かどうか | True/False |
is_month_end |
月末かどうか | True/False |
日付の演算
日付の加減算
例
import pandas as pd
# 日付を作成
date = pd.Timestamp("2024-01-15")
print(f"基準日: {date}")
print()
# 日数の加減算
print(f"+3日: {date + pd.Timedelta(days=3)}")
print(f"-5日: {date - pd.Timedelta(days=5)}")
print()
# 日付の差
date1 = pd.Timestamp("2024-01-01")
date2 = pd.Timestamp("2024-01-15")
print(f"日付の差: {date2 - date1}")
print(f"日数の差: {(date2 - date1).days}")
print()
# 日付 Series の演算
dates = pd.date_range("2024-01-01", periods=5, freq="D")
print("日付 + 3日:")
print(dates + pd.Timedelta(days=3))
# 日付を作成
date = pd.Timestamp("2024-01-15")
print(f"基準日: {date}")
print()
# 日数の加減算
print(f"+3日: {date + pd.Timedelta(days=3)}")
print(f"-5日: {date - pd.Timedelta(days=5)}")
print()
# 日付の差
date1 = pd.Timestamp("2024-01-01")
date2 = pd.Timestamp("2024-01-15")
print(f"日付の差: {date2 - date1}")
print(f"日数の差: {(date2 - date1).days}")
print()
# 日付 Series の演算
dates = pd.date_range("2024-01-01", periods=5, freq="D")
print("日付 + 3日:")
print(dates + pd.Timedelta(days=3))
日付オフセット
例
import pandas as pd
date = pd.Timestamp("2024-01-15")
print(f"基準日: {date}")
print()
# 月初/月末
print(f"月初: {date + pd.offsets.MonthBegin(1)}")
print(f"月末: {date + pd.offsets.MonthEnd(1)}")
print()
# 年のオフセット
print(f"1年加算: {date + pd.DateOffset(years=1)}")
print(f"1月減算: {date + pd.DateOffset(months=-1)}")
print()
# 営業日
print(f"次の月曜: {date + pd.offsets.Week(weekday=0)}")
date = pd.Timestamp("2024-01-15")
print(f"基準日: {date}")
print()
# 月初/月末
print(f"月初: {date + pd.offsets.MonthBegin(1)}")
print(f"月末: {date + pd.offsets.MonthEnd(1)}")
print()
# 年のオフセット
print(f"1年加算: {date + pd.DateOffset(years=1)}")
print(f"1月減算: {date + pd.DateOffset(months=-1)}")
print()
# 営業日
print(f"次の月曜: {date + pd.offsets.Week(weekday=0)}")
タイムゾーンの処理
例
import pandas as pd
# タイムゾーンなしの時刻を作成
dates = pd.date_range("2024-01-01 10:00", periods=3, freq="H")
print("タイムゾーンなし:")
print(dates)
print()
# タイムゾーンを設定
dates_utc = dates.tz_localize("UTC")
print("UTC タイムゾーンを設定:")
print(dates_utc)
print()
# タイムゾーンを変換
dates_shanghai = dates_utc.tz_convert("Asia/Shanghai")
print("上海タイムゾーンに変換:")
print(dates_shanghai)
# タイムゾーンなしの時刻を作成
dates = pd.date_range("2024-01-01 10:00", periods=3, freq="H")
print("タイムゾーンなし:")
print(dates)
print()
# タイムゾーンを設定
dates_utc = dates.tz_localize("UTC")
print("UTC タイムゾーンを設定:")
print(dates_utc)
print()
# タイムゾーンを変換
dates_shanghai = dates_utc.tz_convert("Asia/Shanghai")
print("上海タイムゾーンに変換:")
print(dates_shanghai)
実践:売上データ分析
例
import pandas as pd
# 売上データをシミュレート
df = pd.DataFrame({
"日付": pd.date_range("2024-01-01", periods=30, freq="D"),
"売上高": [100, 150, 120, 180, 200, 90, 80] * 4 + [100, 100]
})
df["日付"] = pd.to_datetime(df["日付"])
print("売上データ:")
print(df.head(10))
print()
# 曜日ごとに集計
print("曜日ごとの平均売上高:")
weekday_sales = df.groupby(df["日付"].dt.day_name())["売上高"].mean()
print(weekday_sales)
print()
# 月ごとに集計
print("月ごとの集計:")
df["月"] = df["日付"].dt.to_period("M")
monthly_sales = df.groupby("月")["売上高"].sum()
print(monthly_sales)
print()
# 7日間の移動平均を計算
df["7日間の移動平均"] = df["売上高"].rolling(window=7).mean()
print("7日間の移動平均を追加:")
print(df.head(10))
# 売上データをシミュレート
df = pd.DataFrame({
"日付": pd.date_range("2024-01-01", periods=30, freq="D"),
"売上高": [100, 150, 120, 180, 200, 90, 80] * 4 + [100, 100]
})
df["日付"] = pd.to_datetime(df["日付"])
print("売上データ:")
print(df.head(10))
print()
# 曜日ごとに集計
print("曜日ごとの平均売上高:")
weekday_sales = df.groupby(df["日付"].dt.day_name())["売上高"].mean()
print(weekday_sales)
print()
# 月ごとに集計
print("月ごとの集計:")
df["月"] = df["日付"].dt.to_period("M")
monthly_sales = df.groupby("月")["売上高"].sum()
print(monthly_sales)
print()
# 7日間の移動平均を計算
df["7日間の移動平均"] = df["売上高"].rolling(window=7).mean()
print("7日間の移動平均を追加:")
print(df.head(10))
よくある質問
1、日付形式が統一されていない
使用するpd.to_datetimeときに指定するformatパラメータで形式を明確にして、解析エラーを回避します。
2、タイムゾーンの混同
タイムゾーンをまたぐデータを処理する場合、すべての時刻が統一されたタイムゾーンまたは UTC 時刻を使用するようにしてください。
3、日付演算には Timedelta を使用
日付の加減算にはpd.Timedeltaを使用し、単純な整数の加減算ではありません。
その他の拡張時系列データを処理する場合は、Pandas の強力な日付機能を活用できるよう、日付文字列をできるだけ早く datetime 型に変換することをお勧めします。