Pandas Series.dt.day 属性

Pandas 通用函数Pandas 常用関数


Series.dt.dayPandas で日付時刻から日(日付)を抽出するために使用される属性です。これは dt アクセサの一部で、datetime 型の Series から月の第何日目(1〜31)をすばやく抽出できます。

時系列データ分析では、日単位での分析は一般的なニーズです。例えば、毎月の特定の日を分析したり、周期的なパターンを識別したりします。dt.dayこの属性により、このような操作は簡単かつ効率的になります。

単語の意味: day「日」を意味し、日付の中の日(月の第何日目)を返します。


基本構文とパラメータ

Series.dt.daySeries の dt アクセサの属性で、日を抽出するために使用します。

構文形式

Series.dt.day

パラメータの説明

この属性はパラメータを一切必要とせず、datetime Series の日情報に直接アクセスします。

戻り値の説明

  • 戻り値:日(1〜31)を含む整数 Series を返します。
  • 効果:datetime64 型の Series から日付の日の部分を抽出し、1 から 31 の整数を返します。

実例

簡単なものから複雑なものまでの一連の例を通して、Series.dt.dayの使い方を徹底的にマスターしましょう。

例1:基本の使い方 - 日の抽出

実例

import pandas as pd

# 1. 日時の Series を作成
print("=== 日時 Series の作成 ===")
dates = pd.Series([
    '2023-01-15',
    '2023-02-20',
    '2023-03-05',
    '2023-04-30',
    '2023-05-25',
    '2023-12-31'
])

# datetime 型に変換
datetime_series = pd.to_datetime(dates)
print("元の日付:")
print(datetime_series)

# 2. dt.day を使用して日を抽出
print("n=== dt.day を使用して日を抽出 ===")
days = datetime_series.dt.day
print("日:")
print(days)

# 3. 年月日を同時に抽出
print("n=== 年月日を同時に抽出 ===")
datetime_series = pd.to_datetime(dates)
df = pd.DataFrame({
    '元の日付': datetime_series,
    '年': datetime_series.dt.year,
    '月': datetime_series.dt.month,
    '日': datetime_series.dt.day
})
print(df)

# 4. 各月の日数を確認
print("n=== 各月の日数 ===")
dates_full = pd.date_range('2023-01-01', periods=12, freq='MS')
days_in_month = dates_full.dt.days_in_month
print(pd.DataFrame({
    '月': dates_full,
    '日数': days_in_month
}))

# 5. うるう年の2月の日数
print("n=== うるう年の2月の日数 ===")
leap_feb = pd.Timestamp('2024-02-01').days_in_month
print(f"2024年2月の日数: {leap_feb}")
non_leap_feb = pd.Timestamp('2023-02-01').days_in_month
print(f"2023年2月の日数: {non_leap_feb}")

実行結果:

=== 创建日期时间 Series ===
0   2023-01-15
1   2023-02-20
2   2023-03-05
3   2023-04-30
4   2023-05-25
5   2023-12-31
dtype: datetime64[ns]

=== 使用 dt.day 提取天 ===
天:
0    15
1    20
2     5
3    30
4    25
5    31
dtype: int64

=== 同时提取年月日 ===
       原始日期  年  月  日
0 2023-01-15  2023  1  15
1 2023-02-20  2023  2  20
2 2023-03-05  2023  3   5
3 2023-04-30  2023  4  30
4 2023-05-25  2023  5  25
5 2023-12-31  2023 12  31

=== 各月的天数 ===
         月份  天数
0  2023-01-01  31
1  2023-02-01  28
2  2023-03-01  31
3  2023-04-01  30
4  2023-05-01  31
5  2023-06-01  30
6  2023-07-01  31
7  2023-08-01  31
8  2023-09-01  30
9  2023-10-01  31
10 2023-11-01  30
11 2023-12-01  31

=== 闰年2月天数 ===
2024年2月天数: 29
2023年2月天数: 28

コードの解説:

  1. dt.day1〜31 の整数を返し、月の第何日目かを表します。
  2. 年月日を同時に抽出して、新しい DataFrame を作成できます。
  3. days_in_monthこの属性を使用すると毎月の日数を取得でき、月末の日付の処理に役立ちます。
  4. 2024年はうるう年で、2月は29日あります。2023年は平年で、2月は28日あります。

例2:日ごとのフィルタリングと分析

実例

import pandas as pd
import numpy as np

# 日付を含むデータセットを作成
print("=== 取引データの作成 ===")
np.random.seed(100)

# 30日分のデータを生成
dates = pd.date_range('2023-03-01', periods=30, freq='D')
df = pd.DataFrame({
    'date': dates,
    'transactions': np.random.randint(50, 200, 30),
    'revenue': np.random.randint(5000, 20000, 30)
})

# 日を抽出
df['day'] = df['date'].dt.day
print(df.head(15))

# 特定の日のレコードをフィルタリング(例:毎月15日)
print("n=== 毎月15日の取引 ===")
day_15 = df[df['day'] == 15]
print(day_15)

# 月の前半と後半にフィルタリング
print("n=== 前半 vs 後半 ===")
df['half'] = df['day'].apply(lambda x: '前半' if x <= 15 else '後半')
half_stats = df.groupby('half')['transactions'].agg(['sum', 'mean']).round(2)
half_stats.columns = ['総取引数', '平均取引数']
print(half_stats)

# 日ごとに集計
print("n=== 日ごとの平均収入の集計 ===")
daily_avg = df.groupby('day')['revenue'].mean().round(2)
print(daily_avg)

# 収入が最も高い日を見つける
print("n=== 収入が最も高い日と最も低い日 ===")
max_day = df.loc[df['revenue'].idxmax()]
min_day = df.loc[df['revenue'].idxmin()]
print(f"最高収入: {max_day['date'].date()}、金額 {max_day['revenue']}")
print(f"最低収入: {min_day['date'].date()}、金額 {min_day['revenue']}")

実行結果:

=== 创建交易数据 ===
         date  transactions  revenue  day
0  2023-03-01             73  16200    1
1  2023-03-02            163  18800    2
2  2023-03-03             76   9600    3
3  2023-03-04             83  10500    4
4  2023-03-05            136  16200    5
5  2023-03-06             86  11700    6
6  2023-03-07             87  13400    7
7  2023-03-08            168  14200    8
8  2023-03-09            163  15800    9
9  2023-03-10             82  11000   10
10 2023-03-11            106  14600   11
11 2023-03-12            152  15900   12
12 2023-03-13            数据截断...

=== 每月15号的交易 ===
        date  transactions  revenue  day
14  2023-03-15            104  12900   15

=== 上半月 vs 下半月 ===
        总交易数  平均交易数
下半月   2117  111.42
上半月   1873  117.06

=== 按天统计平均收入 ===
day
1     16200.00
2     18800.00
...

=== 收入最高和最低的天 ===
最高收入: 2023-03-02,金额 18800
最低收入: 2023-03-03,金额 9600

コードの解説:

  • 日ごとにフィルタリングやグループ分析ができます。
  • 日を月の前半と後半に分けて分析できます。
  • idxmax()とidxmin()最大値・最小値に対応するレコードをすばやく見つけられます。

例3:月末の日付処理

実例

import pandas as pd

# 1. 異なる月の最後の日を処理
print("=== 各月の最後の日 ===")
dates = pd.date_range('2023-01-01', periods=12, freq='MS')
print("毎月の最初の日:")
print(dates)

# 毎月の最後の日を取得
last_days = dates + pd.offsets.MonthEnd(0)
print("n毎月の最後の日:")
print(last_days)

# 2. 月末かどうかを判定
print("n=== 月末かどうかの判定 ===")
test_dates = pd.Series([
    '2023-01-30',  # 1月30日(月末ではない)
    '2023-01-31',  # 1月31日(月末)
    '2023-02-28',  # 2月28日(平年)
    '2023-04-30',  # 4月30日(月末)
])

dt_series = pd.to_datetime(test_dates)
is_month_end = dt_series.is_month_end

result = pd.DataFrame({
    '日付': dt_series,
    '月末かどうか': is_month_end
})
print(result)

# 3. 月初の日付処理
print("n=== 月初かどうかの判定 ===")
is_month_start = dt_series.is_month_start
result['月初かどうか'] = is_month_start
print(result)

# 4. 月の日数が異なる場合の処理
print("n=== 月の日数が異なる場合の処理 ===")
dates_to_check = pd.Series([
    '2023-01-31',  # 有効な日付
    '2023-02-30',  # 無効な日付(2月に30日はない)
])

# 変換を試みて無効な日付を処理
try:
    valid_dates = pd.to_datetime(dates_to_check, errors='coerce')
    print("変換後の日付:")
    print(valid_dates)
    print("n各日付に対応する日:")
    print(valid_dates.dt.day)
except Exception as e:
    print(f"エラー: {e}")

実行結果:

=== 各月最后一天 ===
每月第一天:
DatetimeIndex(['2023-01-01', '2023-02-01', '2023-03-01', '2023-04-01',
               '2023-05-01', '2023-06-01', '2023-07-01', '2023-03-01',
               '2023-09-01', '2023-10-01', '2023-11-01', '2023-12-01'],
              dtype='datetime64[ns]', freq=None)

每月最后一天:
DatetimeIndex(['2023-01-31', '2023-02-28', '2023-03-31', '2023-04-30',
               '2023-05-31', '2023-06-30', '2023-07-31', '2023-03-31',
               '2023-09-30', '2023-10-31', '2023-11-30', '2023-12-31'],
              dtype='datetime64[ns]', freq=None)

=== 判断是否为月末 ===
         日期  是否为月末
0 2023-01-30    False
1 2023-01-31     True
2 2023-02-28     True
3 2023-04-30     True

=== 判断是否为月初 ===
         日期  是否为月末  是否为月初
0 2023-01-30    False    False
1 2023-01-31    False    False
2 2023-02-28    False    False
3 2023-04-30    False    False

=== 月份天数不一致的处理 ===
转换后的日期:
0   2023-01-31
1          NaT
Name: date, dtype: datetime64[ns]

各日期对应的天:
0    31.0
1     NaN

コードの解説:

  • is_month_endこの属性を使用すると月末かどうかを判定できます。
  • is_month_startこの属性を使用すると月初かどうかを判定できます。
  • pd.offsets.MonthEnd(0)当月の最後の日を取得できます。
  • 無効な日付を処理する場合は、errors='coerce'を使用して無効な日付を NaT に変換できます。

注意事項

重要な注意:

  • Series.dt.daydatetime64 型の Series にのみ使用できます。
  • 返される日の範囲は 1〜31 で、具体的な最大値は月によって異なります(2月は最大28/29日、4/6/9/11月は30日、その他の月は31日)。
  • を使用することで、dt.days_in_month毎月の日数を取得できます。
  • 欠損値(NaT)を含むデータを処理する場合、dt.day対応する位置に NaT が返されます。

Pandas 常用函数Pandas 常用関数

その他の拡張