Сравнение даты в столбце x в строке и значения печати столбца y

#python #pandas #datetime

Вопрос:

Я относительно новичок в языке программирования python и поставил перед собой цель изучить python в своем небольшом проекте. Теперь я борюсь с двумя (вероятно) небольшими проблемами. В общем, я хотел бы сравнить даты рождения с текущей датой. Если дата рождения в столбце «день рождения» = сегодня, имя человека должно быть напечатано в предложении.

Первая проблема, с которой я сталкиваюсь, заключается в том, что мне нужно сравнить день и месяц, но не год, и я не могу этого понять. Вторая проблема заключается в том, что я не могу понять, как я могу напечатать имя человека, у которого сегодня день рождения. Я попытался пройти через индекс «имя», но тогда будет напечатан весь индекс. Таблица и код прилагаются. Заранее благодарю вас за вашу помощь.

фамилия имя День рождения
Любовь Дэвид 07.05.1986
Ненавидеть Роберт 17.12.1976
Мир Откровенный 02.09.2021

Последний с днем рождения 02.09.2021 просто изменен, чтобы получить истинный результат.

Ввод

 from datetime import date
from datetime import timedelta
from openpyxl import load_workbook

wb=load_workbook("U:\Python\untitled\Birthdaylist.xlsx")

ws=wb["Sheet1"]
import pandas as pd
df=pd.DataFrame(ws.values)
df.columns=df.iloc[[0]].values.tolist()[0]
df=df[1:]
df.head()

for i in df["Birthday"]:
    if i.date()< date.today():
       print("It's no one's birthday today!")
    if i.date() == date.today():
       print("Today is ",(df["First Name"]), "'s birthday")
    if date.today() < i.date() < (date.today()  timedelta(days=3)):
       print(df["First Name"], "'s birthday is on ", df["Birthday"].date, ".")
 

Выход

 It's no one's birthday today!
It's no one's birthday today!
It's no one's birthday today!
It's no one's birthday today!
It's no one's birthday today!
Today is  1     David
2    Robert
3     Frank
4     Julia
5     Marie
Name: First Name, dtype: object 's birthday
 

Ответ №1:

Вы хотите сделать это в панд (похоже, согласно тегам)?

 # read file
df = pd.read_excel('Birthdaylist.xlsx')

# ensure datetime
df['Birthday'] = pd.to_datetime(df['Birthday'], dayfirst=True)

# set up condition for birthday
today = pd.to_datetime('today', dayfirst=True)
has_birthday = ( df['Birthday'].dt.month.eq(today.month)
                amp;df['Birthday'].dt.year.eq(today.year)
               )

# slice dataframe
df[has_birthay]
 

выход:

   Last Name First Name   Birthday
2     Peace      Frank 2021-09-02
 

Печатная часть:

 if len(df[has_birthday])>0:
    for _, row in df[has_birthday].iterrows():
        print(f"Today is {row['First Name']}'s birthday") # NB. prints several rows if multiple birthdays
else:
    print("It's no one's birthday today!")
 

Комментарии:

1. Большое спасибо. Я попробую сделать это таким образом и дам вам знать, как это сработало.

2. Большое вам спасибо @mozway pd.read_excel как-то не работает. но это не было проблемой. Остальная часть кода работает отлично.

Ответ №2:

Сначала вычислите день рождения за текущий год, затем вычтите текущую дату, чтобы получить разницу в днях:

 today = pd.Timestamp.today().date()
df['Birthday'] = pd.to_datetime(df['Birthday'], format='%d.%m.%Y')
df['When'] = df['Birthday'].apply(lambda x: x.replace(year=today.year))
df['Days'] = df['When'].dt.date.sub(today).dt.days
 

На данный момент ваш фрейм данных выглядит следующим образом:

 >>> df
  Last Name First Name   Birthday       When  Days
0      Love      David 1986-09-04 2021-05-07     2
1      Hate     Robert 1976-12-17 2021-12-17   106
2     Peace      Frank 2021-09-02 2021-09-02     0
 

Теперь вы можете отфильтровать свой фрейм данных:

 # Birthday today
>>> df.loc[df['Days'] == 0, 'First Name']
2    Frank
Name: First Name, dtype: object

# Birthday in next 3 days
>>> df.loc[df['Days'].between(1, 3), 'First Name']
0    David
Name: First Name, dtype: object
 

Комментарии:

1. Большое спасибо. Я попробую сделать это таким образом и дам вам знать, как это сработало.

2. Спасибо @Corralien этот метод также хорош.

Ответ №3:

Я предполагаю, что ваш столбец «День рождения» — это строки, а не дата/время, если так, вы можете разделить его с помощью '.' указателя на день, месяц и год, используя .str.split('.', expand=True) и преобразуя эти столбцы в регистры.

Затем вы можете использовать datetime для получения сегодняшней даты и использовать ее pandas.loc для фильтрации по месяцам и дням, чтобы узнать, у кого сегодня день рождения. Раньше я .iloc[0] получал только строку имени, но если в этот день более 1 дня рождения, то вам, вероятно, лучше .to_list() вместо этого вернуть список и повторить его, чтобы напечатать имена тех, у кого сегодня день рождения. Если сегодня нет дней рождения, то переменная Name вернется пустой (т. Е. len(Name) == 0 ).

 import pandas as pd
import datetime

df = pd.DataFrame({'Last Name' : ['Love', 'Hate', 'Peace'],
                   'First Name' : ['David', 'Robert', 'Frank'],
                   'Birthday' : ['07.05.1986', '17.12.1976', '02.09.2021']})

df[['Day', 'Month', 'Year']] = df['Birthday'].str.split('.', expand=True).astype(int)

Today = datetime.datetime.today()

Name = df.loc[(df['Day'] == Today.day) amp; (df['Month'] == Today.month), 'First Name'].iloc[0]
 

Комментарии:

1. Большое спасибо. Я попробую сделать это таким образом и дам вам знать, как это сработало.

2. Большое спасибо. Моя колонка о дне рождения уже была в формате datetime, но большое вам спасибо за то, как решить проблему, если дата является строкой. Я попробовал, и это тоже получилось довольно хорошо, спасибо

3. @Шарлотта не беспокойтесь, обязательно озвучивайте любые полезные ответы и принимайте любой ответ, который подходит вашему вопросу (из того, что вы только что сказали, я представляю один из других ответов, в котором используется преобразование этого столбца в date_time).