首页 > 解决方案 > 如何在函数内将参数声明为 datetime64?

问题描述

我正在尝试应用下一个函数,其中两个datetime64熊猫数据框列是参数:

import datetime
import pandas as pd

def set_dif_months_na(start_date, end_date):
    if (pd.isnull(start_date) and pd.notnull(end_date)):
        return None
    elif (pd.notnull(start_date) and pd.isnull(end_date)):
        return None
    elif (pd.isnull(start_date) and pd.isnull(end_date)):
        return None
    else:
        start_date = datetime.strptime(start_date, "%d/%m/%Y")
        end_date = datetime.strptime(end_date, "%d/%m/%Y")
    return abs((end_date.year - start_date.year) * 12 + (end_date.month - start_date.month))

这个函数的目的是在给定两个日期作为参数的情况下将月差作为整数,否则它必须返回None

当我将它应用于新的熊猫数据框列时:

df['new_col'] = [set_dif_months_na(date1, date2)
                                          for date1,date2 in 
                                          zip(df['date1'], df['date2'])]

出现下一个错误:

TypeError: strptime() 参数 1 必须是 str,而不是 Timestamp

我如何调整函数以将其正确应用于新的 pandas 数据框列?

标签: pythonpandasfunctiondatetime

解决方案


您会看到,pandas用于numpy解析日期,并且与您尝试使用numpy.datetime64的 不直接兼容。datetime.datetime

有几种不同的解决方案,但如果你想使用datetime,在我看来更具可读性,你可以做这样的事情。首先我们定义一个函数在两种数据类型之间进行转换(从这里获取):

def numpy2datetime(date):
    return (datetime.
            datetime.
            utcfromtimestamp(
                            (date - np.datetime64('1970-01-01T00:00:00')) / 
                            np.timedelta64(1, 's'))
                            )

然后你可以通过改变你的功能来做你想做的事情:

start_date = datetime.strptime(start_date, "%d/%m/%Y")
end_date = datetime.strptime(end_date, "%d/%m/%Y")

start_date = numpy2datetime(start_date)
end_date = numpy2datetime(end_date)

这应该有效。不过,我可能会给你一些额外的建议。首先,您可以使用逻辑运算符将所有if和更改elif为单个:or

if pd.isnull(start_date) or pd.isnull(end_date):
    return None
else:
    start_date = numpy2datetime(start_date)
    end_date = numpy2datetime(end_date)
    return abs((end_date.year - start_date.year) * 12 + (end_date.month - start_date.month))

最后一个是关于你的列表理解。您根本不需要zip,因为两列都在同一个数据框中。你可以简单地做:

df['new_col'] = [set_dif_months_na(date1, date2)
                                          for date1,date2 in 
                                          df[['date1','date2']].values]

不知道它是否更快,但至少它更清晰。

希望它有用。如果您还有其他问题,请告诉我们。


推荐阅读