Last updated: Apr 12, 2024
Reading time·4 min
Note: If you got the error DateParseError: day is out of range for month, click on the second subheading.
The Pandas "ValueError: NaTType does not support strftime" occurs when you
incorrectly convert a value to a datetime
object, e.g. when iterating or when
iterating in a for
loop or when using DataFrame.apply()
.
To solve the error, call the pandas.to_datetime()
method with the specific
DataFrame
column.
Here is an example of how the error occurs.
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['2022-01-25', '2022-02-31', '2023-01-01'] }) for date_joined in df['date_joined']: date = pd.to_datetime(date_joined, errors='coerce').strftime('%Y-%m-%d') # ⛔️ ValueError: NaTType does not support strftime print(date)
Notice that we tried using the
pandas.to_datetime() method in a for
loop.
This is not necessary and caused the error.
pandas.to_datetime()
method outside a loopTo solve the error, call the pandas.to_datetime()
method directly.
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['2022-01-25', '2022-02-31', '2023-01-01'] }) date = pd.to_datetime( df['date_joined'], errors='coerce' ).dt.strftime('%Y-%m-%d') print(date)
Running the code sample produces the following output.
0 2022-01-25 1 NaN 2 2023-01-01 Name: date_joined, dtype: object
pandas.to_datetime()
.errors
argument to "coerce"
so that invalid parsing gets
set as NaT
..dt
attribute before calling strftime()
.date = pd.to_datetime( df['date_joined'], errors='coerce' ).dt.strftime('%Y-%m-%d')
The DataFrame
has an invalid date (2022-02-31
), so a NaN
value gets
returned.
If you meant to overwrite the specific date column, use bracket notation.
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['2022-01-25', '2022-02-31', '2023-01-01'] }) df['date_joined'] = pd.to_datetime( df['date_joined'], errors='coerce' ).dt.strftime('%Y-%m-%d') # name salary date_joined # 0 Alice 175.1 2022-01-25 # 1 Bobby 180.2 NaN # 2 Carl 190.3 2023-01-01 print(df)
The code sample converts the values in the date_joined
column to datetime
objects.
You will also get the error if you try to use the
DataFrame.apply()
method to call a function for each row/column or use a
list comprehension to
iterate over the values in the column and then call pandas.to_datetime()
.
Therefore, make sure to only call the pandas.to_datetime()
method directly
with the DataFrame
column that stores dates without iterating over the column.
The Pandas "DateParseError: day is out of range for month" error occurs for 2 main reasons:
DataFrame.apply()
before calling pandas.to_datetime()
.Here is an example of how the error occurs.
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['2022-01-25', '2022-02-31', '2023-01-01'] }) # ⛔️ pandas._libs.tslibs.parsing.DateParseError: day is out of range for month: 2022-02-31, at position 0 df['date_joined'] = df['date_joined'].apply( lambda x: pd.to_datetime(x).strftime('%Y-%m-%d'))
The error in the example occurred because we used the DataFrame.apply()
method
instead of using pandas.to_datetime()
directly with the date column.
Here is how we'd resolve the issue.
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['2022-01-25', '2022-02-31', '2023-01-01'] }) df['date_joined'] = pd.to_datetime( df['date_joined'], errors='coerce' ).dt.strftime('%Y-%m-%d') # name salary date_joined # 0 Alice 175.1 2022-01-25 # 1 Bobby 180.2 NaN # 2 Carl 190.3 2023-01-01 print(df)
dayfirst
to True
If your date format strings start with the day (e.g. DD-MM-YYYY
), set the
dayfirst
argument to True
when calling pandas.to_datetime()
.
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['25-01-2022', '31-02-2022', '01-01-2023'] }) df['date_joined'] = pd.to_datetime( df['date_joined'], errors='coerce', dayfirst=True ).dt.strftime('%Y-%m-%d') # name salary date_joined # 0 Alice 175.1 2022-01-25 # 1 Bobby 180.2 NaN # 2 Carl 190.3 2023-01-01 print(df)
The boolean dayfirst
argument defaults to False
.
The argument specifies the date parsing order.
If it is set to True
, the date is parsed with the day first, e.g. 20/02/2023
is parsed as 2023-02-20
.
The errors
argument is set to "coerce"
so that values that cannot be parsed
get set as NaT
.
You can view the other possible values in this section of the docs.
format
argument to the pandas.to_datetime()
methodNote that we can also pass a format
argument to the pandas.to_datetime()
method instead of calling .dt.strftime()
.
import pandas as pd df = pd.DataFrame({ 'name': ['Alice', 'Bobby', 'Carl'], 'salary': [175.1, 180.2, 190.3], 'date_joined': ['25-01-2022', '31-02-2022', '01-01-2023'] }) df['date_joined'] = pd.to_datetime( df['date_joined'], errors='coerce', format='%d-%m-%Y', dayfirst=True ) # name salary date_joined # 0 Alice 175.1 2022-01-25 # 1 Bobby 180.2 NaT # 2 Carl 190.3 2023-01-01 print(df)
The format
argument is a string that is used to specify the parsing format.
You can view the available directives in this section of the docs.
You can learn more about the related topics by checking out the following tutorials: