Есть ли способ перебрать серию дат и времени pandas, выполняющую функцию?

Я создал пользовательскую функцию, которая описывает сезонность, и хочу добавить новый столбец в фрейм данных, применив эту функцию к ряду объектов datetime в фрейме данных pandas. Я пытаюсь создать список, содержащий значения функции date_season, применяемые к датам в фрейме данных.

Все переменные в функции date_season ниже имеют тип datetime.date, за исключением 'dif', который является datetime.timedelta.

Вот функция:

import datetime as dt
import pandas as pd

def date_season(date):
    year = date.year
    min_season = dt.date(year,1,1)
    max_season = dt.date(year,6,30)
    dif = abs(max_season - date)
    dif_days = dif.days
    x = (((max_season - min_season).days) - dif.days * 2) / (max_season - min_season).days
    seasonality = np.sin(x * (np.pi) / 2)
    return(seasonality)

А вот как создается фрейм данных pandas:

start = dt.date(2017,1,1)
end = dt.date(2019,12,31)
df = pd.DataFrame({'Date': pd.date_range(start, end, freq = "D")})

Попытка создать новый список с параметром сезонности:

z = []
for index, row in df.iterrows():
    z.append(date_season(row.Date))

Это возвращает сообщение об ошибке:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-105-63e9cb35ed55> in <module>()
      1 z = []
      2 for index, row in df.iterrows():
----> 3     z.append(date_season(row.Date))

<ipython-input-71-5e2b35e24e38> in date_season(date)
      3     min_season = dt.date(year,1,1)
      4     max_season = dt.date(year,6,30)
----> 5     dif = abs(max_season - date)
      6     dif_days = dif.days
      7     x = (((max_season - min_season).days) - dif.days * 2) / (max_season - min_season).days

pandas\_libs\tslibs\timestamps.pyx in 
pandas._libs.tslibs.timestamps._Timestamp.__sub__()

TypeError: descriptor '__sub__' requires a 'datetime.datetime' object but received a 'datetime.date'

Попытка:

new_df = df.apply(lambda x: date_season(x))

возвращается

AttributeError: ("'Series' object has no attribute 'year'", 'occurred at index Date')

Не уверен, почему для этого требуется объект datetime.datetime, потому что функция работает с одиночными входами в формате datetime.date. Есть ли более простой способ перебрать даты и создать новый столбец с результатами этой функции?

Вызов df.apply применит функцию к каждому столбцу в df. Ваша функция принимает один объект datetime в качестве входных данных. Что вам нужно сделать, так это использовать df.applymap(date_season) (если все столбцы являются объектами даты и времени), в противном случае вам нужно применить к одному столбцу, например df['date_column'].apply(date_season).

iamchoosinganame 30.05.2019 17:15
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
687
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно определить min_season и max_season как объекты datetime pandas вместо встроенного класса datetime python. Это сбивает с толку, но они не полностью взаимозаменяемы.

def date_season(date):
    year = date.year
    #use pandas.datetime
    min_season = pd.datetime(year,1,1)
    max_season = pd.datetime(year,6,30)
    dif = abs(max_season - date)
    dif_days = dif.days
    x = (((max_season - min_season).days) - dif.days * 2) / (max_season - min_season).days
    seasonality = np.sin(x * (np.pi) / 2)
    return(seasonality)

Теперь вы можете использовать applymap для всего вашего фрейма данных или применить его к одному столбцу.

new_df = df.applymap(date_season)

или

df['Date'].apply(date_season)

Потрясающий! Это работает. Большое спасибо за ответ!

Gambit1337 30.05.2019 18:03

Другие вопросы по теме