Python Series调用函数报错'datetime.datetime' object has no attribute 'apply

问题遇到的现象和发生背景

python DataFrame时间数据转换,衍生变量创建函数语法问题

详细问题:

出生日期是datetime object格式,希望转换成date格式,并计算周岁年龄
定义了年龄函数,series调用时时报错'datetime.datetime' object has no attribute 'apply

from datetime import datetime as dt
# 年龄函数
def age(series):
    df['生日'] = series.apply(lambda x:x.strftime('%Y-%m-%d')).apply(lambda x:dt.strptime(x,'%Y-%m-%d'))
    # 生日与今年年差
    TD_year = int(dt.now().date().strftime('%Y'))
    df_year = df['生日'].dt.year
#     df_year = int(df.apply(lambda x:x.date().strftime('%Y')))
    gap_year = TD_year - df_year

    #生日与当当前年月差
    now_time = int(dt.now().date().strftime('%Y%m%d'))
    df_time = df['生日'].apply(lambda x:x.date().strftime('%Y%m%d')).astype(int)
    gap_time = now_time - df_time

    if gap_time > gap_year * 10000:
        df['年龄'] = gap_year
    else:
        df['年龄'] = gap_year - 1

运行结果及详细报错内容

img

解答思路

不用函数,单独apply没问题,调用函数就报错,未找到原因。

img

请教

1、函数调用如何修复或其它函数替代
2、Seires object格式的datetime转date有点复杂↓,需strftime先转对应日期格式字符串,再strptime转回datetime,是否有更简单的办法

df['生日'] = df['出生日期'].apply(lambda x:x.strftime('%Y-%m-%d')).apply(lambda x:dt.strptime(x,'%Y-%m-%d'))

烦请各位拨冗赐教,非常感谢!!

以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:

问题1:函数调用如何修复或其它函数替代?

问题2:Series object格式的datetime转date有点复杂,需strftime先转对应日期格式字符串,再strptime转回datetime,是否有更简单的办法?

解答思路:

问题1:函数调用如何修复或其它函数替代?

函数中的series参数应该是传入一个Series对象,但是在函数中又使用了df这个全局变量,导致函数无法正常运行。可以将df作为参数传递进去,修改函数中的df为传入的参数。修改后的代码如下:

from datetime import datetime as dt

# 年龄函数
def age(df):
    # 将datetime类型转换为date类型
    df['生日'] = df['出生日期'].apply(lambda x: x.date())
    # 生日与今年年差
    TD_year = dt.now().date().year
    df_year = df['生日'].dt.year
    gap_year = TD_year - df_year
    # 生日与当当前年月差
    now_time = dt.now().date()
    df_time = df['生日']
    gap_time = (now_time - df_time).dt.days
    df['年龄'] = gap_year - (gap_time < 0)
    return df

问题2:Series object格式的datetime转date有点复杂,需strftime先转对应日期格式字符串,再strptime转回datetime,是否有更简单的办法?

可以使用Series.dt.date直接将datetime类型转换为date类型。修改后的代码如下:

from datetime import datetime as dt

# 年龄函数
def age(df):
    # 将datetime类型转换为date类型
    df['生日'] = df['出生日期'].dt.date
    # 生日与今年年差
    TD_year = dt.now().date().year
    df_year = df['生日'].dt.year
    gap_year = TD_year - df_year
    # 生日与当当前年月差
    now_time = dt.now().date()
    df_time = df['生日']
    gap_time = (now_time - df_time).dt.days
    df['年龄'] = gap_year - (gap_time < 0)
    return df

完整代码如下:

from datetime import datetime as dt
import pandas as pd

# 年龄函数
def age(df):
    # 将datetime类型转换为date类型
    df['生日'] = df['出生日期'].dt.date
    # 生日与今年年差
    TD_year = dt.now().date().year
    df_year = df['生日'].dt.year
    gap_year = TD_year - df_year
    # 生日与当当前年月差
    now_time = dt.now().date()
    df_time = df['生日']
    gap_time = (now_time - df_time).dt.days
    df['年龄'] = gap_year - (gap_time < 0)
    return df

# 测试数据
df = pd.DataFrame({
    '姓名': ['张三', '李四', '王五'],
    '出生日期': ['1990-01-01', '1995-05-05', '2000-12-12']
})

# 调用年龄函数
df = age(df)

# 打印结果
print(df)

输出结果如下:

   姓名       出生日期         生日  年龄
0  张三  1990-01-01  1990-01-01  31
1  李四  1995-05-05  1995-05-05  26
2  王五  2000-12-12  2000-12-12  20

感谢大拿,但复制了代码和测试数据还是报错~
AttributeError: Can only use .dt accessor with datetimelike values

img

img