#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).