df = pd.DataFrame({'name': ['John', 'Jane', 'Max', 'David'], 'birthdate': [
    datetime(1990, 1, 1), datetime(1957, 4, 3), datetime(1987, 2, 3),
    datetime(1964, 2, 12)]})

def get_birthdays(df_x):
    d = {'name': [], 'birthday': []}
name = df_x.iloc[0]['name']
original = df_x.iloc[0]['birthdate']
for year in range(2016, 2019):
    d['name'].append(name)
d['birthday'].append(original.replace(year=year))
return pd.DataFrame(d)
print(df.groupby('name', group_keys=False).apply(get_birthdays).reset_index(
    drop=True))
Multiple results for each individual row (one-to-many) with Pandas