Свойство Pandas Series.dt.day
Series.dt.day— это атрибут Pandas, используемый дляизвлечения дня (даты) из даты-времени. Он является частью аксессора dt и позволяет быстро извлечь день месяца (1-31) из Series с datetime.
При анализе данных временных рядов анализ по дням является обычным требованием, например анализ конкретных дней каждого месяца, выявление периодических закономерностей и т. д.dt.dayЭто свойство делает такие операции простыми и эффективными.
Определение слова: dayОно означает «day», то есть возвращает день в дате (день месяца).
Базовый синтаксис и параметры
Series.dt.dayЭто атрибут аксессора dt объекта Series, используемый для извлечения дня.
Формат синтаксиса
Series.dt.day
Описание параметра
Этот атрибут не требует параметров; он напрямую обращается к информации о дне в Series с datetime.
Описание возвращаемого значения
- Возвращаемое значениеВозвращает целочисленный Series, содержащий день (1-31).
- ДействиеИзвлекает часть даты, соответствующую дню, из Series с datetime64, возвращая целые числа от 1 до 31.
Пример
Давайте досконально освоим с помощью серии примеров от простых к сложнымSeries.dt.dayиспользование этого свойства.
Пример 1: Базовое использование - Извлечение дня
Пример
# 1. Создайте Series с datetime
print("=== Создание Series типа datetime ===")
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. Количество дней в феврале в високосном году
print("\n=== Количество дней в феврале в високосном году ===")
leap_feb = pd.Timestamp('2024-02-01').days_in_month
print(f"Количество дней в феврале 2024: {leap_feb}")
non_leap_feb = pd.Timestamp('2023-02-01').days_in_month
print(f"Количество дней в феврале 2023: {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
Анализ кода:
dt.dayВозвращает целые числа от 1 до 31, представляющие день месяца.- Можно одновременно извлечь год, месяц и день, чтобы создать новый DataFrame.
days_in_monthЭтот атрибут позволяет получить количество дней в каждом месяце, что очень полезно для работы с датами конца месяца.- 2024 — високосный год, в феврале 29 дней; 2023 — обычный год, в феврале 28 дней.
Пример 2: Фильтрация и анализ по дням
Пример
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': даты,
'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=== Первая половина против второй половины ===")
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 = ['Total transactions', 'Average transactions']
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: Обработка дат конца месяца
Пример
# 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', # 30 января (не последний день месяца)
'2023-01-31', # 31 января (последний день месяца)
'2023-02-28', # 28 февраля (невисокосный год)
'2023-04-30', # 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', # Некорректная дата (в феврале нет 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.dayЕго можно использовать только для Series типа datetime64.- Возвращаемый диапазон дней — 1–31; точный максимум зависит от месяца (в феврале максимум 28/29 дней, в апреле/июне/сентябре/ноябре — 30 дней, а в остальных месяцах — 31 день).
- Вы можете использовать
dt.days_in_monthчтобы получить количество дней в каждом месяце.- При обработке данных, содержащих пропущенные значения (NaT),
dt.dayNaT будет возвращено в соответствующей позиции.
Другие расширения
Pandas: общие функции