python - 给定一个生日列,如何计算一个人当天的年龄?
问题描述
vanco.csv
firstname,secondname,birthdate
vanco,grizov,3-16-1983
vlado,stojanov,6-24-1982
goce,grizov,7-18-1985
代码
import pandas as pd
from datetime import date
data=pd.read_csv(r'C:\\Users\\User\\Desktop\\test\\vanco.csv')
data.head(3)
print(data)
data.birthdate=pd.to_datetime(data.birthdate)
data.head(3)
print (data)
def calculate_age(born):
today = date.today()
return today.year - born.year - ((today.month, today.day) < (born.month, born.day))
data['birthdate'].apply(lambda x: calculate_age(x))
print(data)
从代码中,我在 PyCharm 中有这个输出
我编写代码,然后将 csv 文件中的列出生日期转换为日期时间对象:
然后我编写一个函数来创建和返回年龄birthdate
def calculate_age(born):
today = date.today()
return today.year - born.year - ((today.month, today.day) < (born.month, born.day))
data['birthdate'].apply(lambda x: calculate_age(x))
print(data)
从代码中,我在 PyCharm 控制台中有这个输出
filename secondname birthdate
0 vanco grizov 3-16-1983
1 vlado stojanov 6-24-1982
2 goce grizov 7-18-1985
filename secondname birthdate
0 vanco grizov 1983-03-16
1 vlado stojanov 1982-06-24
2 goce grizov 1985-07-18
filename secondname birthdate
0 vanco grizov 1983-03-16
1 vlado stojanov 1982-06-24
2 goce grizov 1985-07-18
- 预期的输出是带有年龄的列,应添加到数据框中。
解决方案
- 这个答案假设所需的输出是从生日到今天的年龄,以年为单位。
(today - bd)
返回总天数的值。- 除以
pd.Timedelta(days=365.25)
, 得到年数。365.25
因为一年的长度会改变
- 除以
- 有关 timedeltas 和转换为不同时间单位的更多详细信息,请参阅以小时和分钟为单位计算 Pandas DataFrame 两列之间的时间差。
- 原始函数返回一个值,但返回的值没有分配回数据框,类似于
df['age (years)'] = calc_age(df.birthdate)
,这就是这些值显示在控制台中的原因。 - 此外,没有必要使用
.apply
. 这会迭代地应用该函数,这就是控制台有多个输出的原因。
import pandas as pd
from datetime import date
# read the file in and covert the birthdate column to a datetime
df = pd.read_csv('vanco.csv', parse_dates=['birthdate'])
# function
def calc_age(bd: pd.Series) -> pd.Series:
today = pd.to_datetime(date.today()) # convert today to a pandas datetime
return (today - bd) / pd.Timedelta(days=365.25) # divide by days to get years
# call function and assign the values to a new column in the dataframe
df['age (years)'] = calc_age(df.birthdate)
# display(df)
firstname secondname birthdate age (years)
0 vanco grizov 1983-03-16 37.48118
1 vlado stojanov 1982-06-24 38.20671
2 goce grizov 1985-07-18 35.14031
或者
- 使用
dateutil
模块,它有更丰富的方法选择relativedelta
将补偿闰年- 用于
.years
从relativedelta
对象中仅提取年份部分。
# updated function with relativedelta
def calc_age(bd: pd.Series):
today = pd.to_datetime(date.today())
return bd.apply(lambda x: relativedelta(today, x).years)
# function call
df['age (years)'] = calc_age(df.birthdate)
# display(df)
firstname secondname birthdate age (years)
0 vanco grizov 1983-03-16 37
1 vlado stojanov 1982-06-24 38
2 goce grizov 1985-07-18 35
# the output if .years is removed from the calc_age function
firstname secondname birthdate age (years)
0 vanco grizov 1983-03-16 relativedelta(years=+37, months=+5, days=+22)
1 vlado stojanov 1982-06-24 relativedelta(years=+38, months=+2, days=+14)
2 goce grizov 1985-07-18 relativedelta(years=+35, months=+1, days=+20)
推荐阅读
- vue.js - vue/cli 3 未满足的依赖项
- c - 如何在 C 中以正确的方式从二进制结构中打印位域?
- git - 为什么git要添加父目录?
- javascript - 使用 Angular 从 API 访问数据(格式错误?)
- git - GIT:取消应用存储 - 指定的修订太多
- c# - 如何临时使用 Graphics.TranslateTransform
- heroku - Amazon S3 存储 Wagtail 媒体文件 - 仅 Heroku 上的服务器 500 错误
- angular - 为什么 [hidden] 在 forkJoin().subscribe() 之后不起作用?
- python - 在python中增加多行的一些列
- ios - IOS/Objective-C:代码中创建的tableview的无阻碍滚动(去除橡皮筋效果)