【问题标题】:Pandas: add timedelta column to datetime column (vectorized)Pandas:将 timedelta 列添加到 datetime 列(矢量化)
【发布时间】:2016-11-16 06:51:09
【问题描述】:

我有一个包含两列、一个日期列和一个 int 列的 pandas 数据框,我只想将 int 列(以天为单位)添加到日期列中。我找到了一个使用 df.apply() 的解决方案,但这在我的完整数据集上太慢了。我没有看到大量关于以矢量化方式执行此操作的文档(我能找到的最接近的是 this ),所以我想确保我找到的解决方案是前进的最佳方式。

我的原始数据只是一列字符串,即一列整数(天)。

import pandas as pd
from datetime import timedelta

df = pd.DataFrame([['2016-01-10',28],['2016-05-11',28],['2016-02-23',15],['2015-12-08',30]], 
                  columns = ['ship_string','days_supply'])
print df  

ship_string  days_supply
0  2016-01-10           28
1  2016-05-11           28
2  2016-02-23           15
3  2015-12-08           30

我的第一个想法(有效)是使用 .apply 如下:

def f(x):    
    return x['ship_date'] + timedelta(days=x['days_supply'] )

df['ship_date'] = pd.to_datetime(df['ship_string'])

df['supply_ended'] = df.apply(f,axis = 1)

这行得通,但速度非常慢。我已经在下面发布了我的替代解决方案作为问题的答案,但我想确认它是“最佳实践”。我找不到很多关于将 timedelta 列添加到 pandas 中的日期(尤其是以矢量化方式)的好线程,所以我想我会添加一个对用户更友好的线程,希望它能帮助下一个试图这样做。

【问题讨论】:

    标签: pandas vectorization timedelta


    【解决方案1】:

    解决这些问题的另一种方法:我们可以将时间戳更改为秒,添加或减去您想要的数字,然后再次更改为时间戳。对于一些复杂的时间操作,这种方法会很有用。

        df["ship_string"]=pd.to_datetime(df["ship_string"])
        ls_temp = (df["ship_string"] - pd.Timestamp("1970-01-01")) // pd.Timedelta("1s")
        df["supply_ended"] = pd.to_datetime(ls_temp+df["days_supply"]*(24*3600), unit="s")
    

    【讨论】:

      【解决方案2】:

      完整代码解决方案:

      import pandas as pd
      from datetime import timedelta
      
      df = pd.DataFrame([['2016-01-10',28],['2016-05-11',28],['2016-02-23',15],['2015-12-08',30]], 
                            columns = ['ship_string','days_supply'])
      
      df['ship_date'] = pd.to_datetime(df['ship_string'])
      
      df['time_added'] = pd.to_timedelta(df['days_supply'],'d')
      df['supply_ended'] = df['ship_date'] + df['time_added']
      
      print df
      
        ship_string  days_supply  ship_date  time_added supply_ended
      0  2016-01-10           28 2016-01-10     28 days   2016-02-07
      1  2016-05-11           28 2016-05-11     28 days   2016-06-08
      2  2016-02-23           15 2016-02-23     15 days   2016-03-09
      3  2015-12-08           30 2015-12-08     30 days   2016-01-07
      

      如果这不是一个好的矢量化解决方案,请在下面的 cmets 中告诉我,我会进行编辑。

      【讨论】:

      • 这是一个很好的解决方案,也许一行更好df['supply_ended'] = pd.to_datetime(df['ship_string']) + pd.to_timedelta(df['days_supply'],'d'),如果不需要创建新列。
      • 我找不到函数 pd.to_timedelta,因为 DateOffset 不适用于 Series,因此感谢您发布该解决方案!
      • ,'d'这个小家伙……MVP
      猜你喜欢
      • 1970-01-01
      • 2017-04-06
      • 1970-01-01
      • 2020-11-26
      • 2021-12-28
      • 2016-05-21
      • 2018-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多