【问题标题】:Python pandas add a years integer column to a date columnPython pandas 将年份整数列添加到日期列
【发布时间】:2021-07-14 03:46:51
【问题描述】:

我有一个类似于这里讨论的问题How to add a year to a column of dates in pandas 但是在我的情况下,添加到日期列的年数存储在另一列中。这是我不工作的代码:

import datetime
import pandas as pd
df1 = pd.DataFrame( [ ["Tom",5], ['Jane',3],['Peter',1]],  columns = ["Name","Years"])
df1['Date'] = datetime.date.today()
df1['Final_Date'] = df1['Date'] + pd.offsets.DateOffset(years=df1['Years'])

目标是将第 1 行的当前日期添加 5 年,将第 2 行的当前日期添加 3 年,等等。 有什么建议么?谢谢

【问题讨论】:

  • 什么不起作用?
  • 你试过了吗?
  • @Angelo 你在年里有很多不同的价值观吗?
  • 问题基本上是熊猫的时间增量不采用矢量化输入。它抛出TypeError: cannot convert the series to <class 'int'>
  • 对,这正是我的问题。你知道怎么处理吗?谢谢

标签: python pandas dataframe python-datetime


【解决方案1】:

通过将年转换为天,然后添加到转换后的日期时间列来转换为时间增量:

df1['Final_Date'] = pd.to_datetime(df1['Date']) \
    + pd.to_timedelta(df1['Years'] * 365, unit='D')

多年来,to_timedeltaunit='Y' 的使用是 deprecated 并抛出 ValueError

【讨论】:

  • 这种方法的问题是闰年。也就是说,如果 OP 不在确切的月日前后几天,那么这是最简单的方法 :)
【解决方案2】:

假设 Years 中不同值的数量是有限的,你可以试试groupbypd.DateOffset 做类似的操作:

df1['new_date'] = (
    df1.groupby('Years')
       ['Date'].apply(lambda x: x + pd.DateOffset(years=x.name))
)
print(df1)
    Name  Years        Date   new_date
0    Tom      5  2021-07-13 2026-07-13
1   Jane      3  2021-07-13 2024-07-13
2  Peter      1  2021-07-13 2022-07-13

否则您可以提取年、月和日,将 Years 列添加到 year 并重新创建 datetime 列

df1['Date'] = pd.to_datetime(df1['Date'])
df1['new_date'] = (
    df1.assign(year=lambda x: x['Date'].dt.year+x['Years'], 
               month=lambda x: x['Date'].dt.month,
               day=lambda x: x['Date'].dt.day, 
               new_date=lambda x: pd.to_datetime(x[['year','month','day']]))
       ['new_date']
)

同样的结果

【讨论】:

    【解决方案3】:
    import datetime
    import pandas as pd
    df1 = pd.DataFrame( [ ["Tom",5], ['Jane',3],['Peter',1]],  columns = ["Name","Years"])
    df1['Date'] = datetime.date.today()
    df1['Final_date'] = datetime.date.today()
    
    df1['Final_date'] = df1.apply(lambda g: g['Date'] + pd.offsets.DateOffset(years = g['Years']), axis=1)
    
    
    print(df1)
    

    试试这个,当您调用 pd.offsets.DateOffset(years=df1['Years']) 时,您试图添加整个列,而不是列中的 1 个值。

    编辑:由于iterrows 的性能不佳,我从iterrows 更改为矢量化方法

    【讨论】:

    • 除非绝对必要,否则不要使用iterrows;它的性能极差
    • 我同意,尽管我很欣赏这个解决方案,但我需要一个矢量化解决方案
    • @ifly6 你说的对,我忘了考虑性能问题。
    • 嗨 Tomo,欢迎投稿。仅供参考,虽然 apply 用于按行操作(轴 = 1)比 iterrows 好一点,但它仍然不是矢量化解决方案,例如 see this answerthis question 时间示例:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 2023-03-21
    • 1970-01-01
    • 2020-11-11
    • 2021-08-13
    • 2020-05-28
    • 2021-11-02
    相关资源
    最近更新 更多