You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pythonic方式生成含人员月末年龄的DataFrame及建模咨询

问题描述

我有一个包含人员名字、姓氏及出生日期的DataFrame:

import pandas as pd

data = [
    ["John",   "Wayne",   "13.12.2018"],
    ["Max",    "Muster",  "02.06.2016"],
    ["Steve",  "Black",   "11.04.2017"],
    ["Amy",    "Smith",   "10.10.2017"],
    ["July",   "House",   "08.05.2018"],
    ["Anna",   "Whine",   "20.08.2016"],
    ["Charly", "Johnson", "16.07.2016"],
]

people = pd.DataFrame(
    data,
    columns=["first", "last", "birthdate"],
)

people["birthdate"] = pd.to_datetime(people["birthdate"], format="%d.%m.%Y")

我希望生成另一个DataFrame,行与原DataFrame一致,列为一年中的各个月份,数据为对应月末人员的年龄。

当前实现方式如下:

# 生成所有月份的起始日期
months = pd.date_range("2022-01-01", "2022-12-01", freq="MS")

# 计算每个人的年龄
age = pd.DataFrame(data={"first": people["first"], "last": people["last"]})
for value in months:
    last_day_of_month = value + pd.offsets.MonthEnd()
    age[value.strftime("%b")] = (last_day_of_month - people["birthdate"]).astype(
        "timedelta64[Y]"
    )

该实现可正常运行,但想知道是否存在更Pythonic的实现方式。此外,作为Python和Pandas新手,还想咨询:在时间序列数据建模中,更适合将月份设为列还是行?是否有相关最佳实践?


更Pythonic的实现方案

可以利用Pandas的向量化操作替代循环,提升效率和代码简洁性:

import pandas as pd

# 直接生成2022年所有月末日期
month_ends = pd.date_range("2022-01-31", "2022-12-31", freq="M")

# 利用广播机制一次性计算所有人员与所有月末日期的年龄差
# 用365.25天计算更符合实际年龄(考虑闰年),取整得到整数年龄
age_matrix = (month_ends[None, :] - people["birthdate"][:, None]) / pd.Timedelta(days=365.25)
age_matrix = age_matrix.floor().astype(int)

# 合并姓名列与年龄矩阵,构造最终DataFrame
age_df = pd.concat(
    [people[["first", "last"]], 
     pd.DataFrame(age_matrix, columns=month_ends.strftime("%b"))],
    axis=1
)

关键优化点:

  • 直接生成月末日期,省去手动计算MonthEnd()的步骤
  • 用广播机制替代循环,一次完成所有人员的年龄计算,效率更高
  • 采用更精准的年龄计算方式,避免timedelta64[Y]在部分场景下的精度问题

时间序列建模:月份设为列还是行?

没有绝对标准答案,核心看你的数据用途和分析场景:

  • 月份设为列(宽表格式):

    • 适合对比同一人员在不同月份的年龄变化,或做横向统计(比如单个人的年度年龄波动)
    • 优点:直观展示个体的时间维度特征,便于快速查看单条记录的全周期数据
    • 缺点:时间范围扩大(比如多年)时,列数会急剧增加,导致数据稀疏、难以维护
  • 月份设为行(长表格式):

    • 适合时间序列建模(如预测年龄变化、按月份聚合统计),或使用可视化工具做趋势分析
    • 优点:符合Tidy Data原则,便于分组聚合、时间窗口分析,扩展性更强(新增年份只需追加行)
    • 缺点:单条人员记录会被拆分为多行,查看个体全年数据需要额外筛选

最佳实践建议:

  1. 优先用长表格式作为基础存储,它适配绝大多数分析和建模场景,灵活性更高
  2. 如果需要做横向对比或展示,可以用pivot方法将长表转为宽表
  3. 当时间维度超过2年时,强烈推荐长表,避免宽表的列数膨胀问题

内容的提问来源于stack exchange,提问作者zemirco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 08:01:34