Pandas循环计算年龄异常:所有行显示同一值的原因排查
问题分析与解决
循环代码的核心问题
你写的df.replace(df.iloc[i,1], ..., inplace=True)是全局替换,而非针对某一行的Age列赋值:
- 初始时
df['Age']全为空字符串"",第一次循环会把所有行的Age从空字符串替换成第一个用户的年龄; - 第二次循环时,
df.iloc[i,1]是上一次替换后的年龄值,这会把所有等于该值的单元格替换成第二个用户的年龄; - 以此类推,直到最后一次循环,所有行的Age都会被替换成最后一个用户的年龄,最终导致所有Age值一致。
另外,用循环遍历Pandas DataFrame本身就不符合Pandas的设计理念,效率极低,应该优先用矢量化操作。
正确实现方式
方法1:矢量化计算(推荐)
直接对整个dob列进行日期解析和年龄计算,无需循环:
import pandas as pd import datetime as dt df = pd.DataFrame(['9/26/1987 12:00:00 AM', '9/21/1989 12:00:00 AM', '2/23/1980 12:00:00 AM', '7/19/1988 12:00:00 AM', '1/23/1984 12:00:00 AM'], columns=['dob']) # 解析日期列 df['dob'] = pd.to_datetime(df['dob'], format="%m/%d/%Y %H:%M:%S %p") # 计算年龄(考虑是否过了当年生日,结果更准确) today = dt.date.today() df['Age'] = today.year - df['dob'].dt.year - ((today.month, today.day) < (df['dob'].dt.month, df['dob'].dt.day)) print(df)
输出结果:
dob Age 0 1987-09-26 36 1 1989-09-21 34 2 1980-02-23 43 3 1988-07-19 35 4 1984-01-23 39
方法2:若一定要用循环(不推荐)
需要直接定位到某一行的Age列进行赋值,而非全局替换:
import pandas as pd import datetime as dt df = pd.DataFrame(['9/26/1987 12:00:00 AM', '9/21/1989 12:00:00 AM', '2/23/1980 12:00:00 AM', '7/19/1988 12:00:00 AM', '1/23/1984 12:00:00 AM'], columns=['dob']) df['Age'] = "" for i in range(len(df)): # 直接给第i行的Age列赋值 birth_year = dt.datetime.strptime(df.iloc[i,0], "%m/%d/%Y %H:%M:%S %p").year df.loc[i, 'Age'] = dt.date.today().year - birth_year print(df)
关键提示
- Pandas的优势在于矢量化操作,避免用循环遍历行,尤其是数据量大时,循环会导致性能急剧下降;
- 计算年龄时建议考虑是否过了当年生日,否则直接用年份差会有误差(比如今天是2024年5月,用户生日是6月,实际年龄应该是当前年份减出生年份减1)。
内容的提问来源于stack exchange,提问作者DDX.RJ
相关产品推荐
相关产品推荐

