So I wanna fill NaN value of the pay date with the date one month after the join date.
Join date | Payday1 |
---|---|
Okt'10 | NaN |
Des'10 | NaN |
My expectation output is:
Join date | Payday1 |
---|---|
Okt'10 | Nov'10 |
Des'10 | Jan'11 |
I try this code:
months = ["Jan", "Feb", "Mar", "Apr","Mei","Jun","Jul","Agt","Sep","Okt","Nov","Des"]
dateIn="Okt'10"
def fill_date():
dateIn=dateIn.split("'")
month, year= dateIn[0], int(dateIn[1])
if month == months[len(months)-1]:
year =1
month=months[0]
else:
for m in months:
if m == month:
month=months[months.index(month) 1]
dateOut=f"{month} {year}"
df['Payday1'] = df['Payday1'].apply(fill_date)
This code is error in this code month=months[months.index(month) 1], it said list index out of range
. So how to fix this code ?
CodePudding user response:
Try:
def fill_date(dt):
mapper = {m: i 1 for i, m in enumerate(months)}
month, year = dt.split("'")
if mapper[month]==12:
return f"Jan'{int(year) 1}"
else:
return f"{months[mapper[month]]}'{year}"
df["Payday1"] = df["Join date"].apply(fill_date)
Input df:
df = pd.DataFrame({"Join date": ["Okt'10", "Des'10"]})
CodePudding user response:
If you want to constrain the index between 0
and len(months)
, you can use the modulo operator %
.
month=months[(months.index(month) 1) % len(months)]
So you would get the following:
def fill_date(dateIn):
dateIn = dateIn.split("'")
month, year = dateIn[0], int(dateIn[1])
year = 1 if month == months[-1] else 0
month = months[(months.index(month) 1) % len(months)]
dateOut = f"{month}'{year}"
return dateOut
CodePudding user response:
I see two methods:
First: add second Jan
at the end of list months
and this may work.
Second: use break
inside for
-loop to exit it when you find first matching element.
All problem is because inside if m == month
you assign new value to month
and in next loops the same line if m == month
compares with different value in month
and it may compare with Des
and tor to get elemenet after Des
. But if you use break
then it will exit afer finding first matching value (and it will not check if m == month
for new value).
Full working code with other changes - ie. you fogot return dateOut
in your code.
months = ["Jan", "Feb", "Mar", "Apr","Mei","Jun","Jul","Agt","Sep","Okt","Nov","Des"]
dateIn = "Okt'10"
import pandas as pd
df = pd.DataFrame({
'Join date': ["Okt'10", "Des'10"],
'Payday1': ["NaN", "NaN"],
})
def fill_date(dateIn):
print(dateIn)
dateIn = dateIn.split("'")
month, year = dateIn[0], int(dateIn[1])
if month == months[-1]:
year = 1
month = months[0]
else:
for m in months:
if m == month:
month = months[months.index(month) 1]
break # <--- HERE
dateOut = f"{month}'{year}"
return dateOut
df['Payday1'] = df['Join date'].apply(fill_date)
print(df)
Result:
Join date Payday1
0 Okt'10 Nov'10
1 Des'10 Jan'11
Probably problem could resolve also for m in months[:-1]:
to skip Des
from list.