基于前一行自动递增Pandas DataFrame中的年份
Pandas实现日期年份自动递增(当前行日期早于前一行时)
问题描述
现有如下Pandas DataFrame,需要实现:当某行的old_value日期早于前一行时,自动为该行日期的年份递增(递增次数根据回滚次数累计),最终得到new_value列的结果。原以为需要递归实现,其实可以用向量化操作高效完成。
示例DataFrame:
import pandas as pd df = pd.DataFrame({ 'old_value': ['2022-11-10', '2022-12-11', '2022-01-10', '2022-01-20', '2022-01-01'], 'new_value': ['2022-11-10', '2022-12-11', '2023-01-10', '2023-01-20', '2024-01-01'] })
解决方案
不需要递归,用Pandas的向量化操作就能高效处理,步骤如下:
- 转换日期类型:先将
old_value列转为datetime类型,方便日期比较和运算 - 计算年份增量:判断每一行日期是否小于前一行,生成布尔序列后做累计求和,得到每行需要增加的年数
- 生成新日期:将累计的年数加到原日期上,得到最终的
new_value
完整代码:
# 转换为datetime类型 df['old_value'] = pd.to_datetime(df['old_value']) # 计算日期回滚的累计次数(即需要增加的年数) # 第一行没有前一行,增量为0;后续行如果当前日期<前一行,标记为1,否则0,累计求和 year_increments = (df['old_value'] < df['old_value'].shift(1)).cumsum() # 生成新日期:原日期加上对应的年数 df['calculated_new_value'] = df['old_value'] + pd.DateOffset(years=year_increments) # 查看结果 print(df)
运行结果会和示例中的new_value完全一致:
old_value new_value calculated_new_value 0 2022-11-10 2022-11-10 2022-11-10 1 2022-12-11 2022-12-11 2022-12-11 2 2022-01-10 2023-01-10 2023-01-10 3 2022-01-20 2023-01-20 2023-01-20 4 2022-01-01 2024-01-01 2024-01-01
原理说明
df['old_value'].shift(1)会把日期列整体下移一行,这样就能和当前行做比较df['old_value'] < df['old_value'].shift(1)生成布尔序列,True表示当前日期比前一行小(需要年份递增)cumsum()对布尔序列累计求和,每遇到一次True,累计值加1,这个值就是当前行需要增加的年数pd.DateOffset(years=...)可以方便地给日期加上指定年数,自动处理闰年等日期问题
内容的提问来源于stack exchange,提问作者DNN
相关产品推荐
相关产品推荐

