【问题标题】:Create pandas column of pd.date_range创建 pd.date_range 的 pandas 列
【发布时间】:2018-09-25 09:00:29
【问题描述】:

我有这样的数据:

import datetime as dt
import pandas as pd
df = pd.DataFrame({'date':[dt.datetime(2018,8,25), dt.datetime(2018,7,21)],
                   'n':[10,7]})

我想创建第三列,其中包含由 pd.date_range 创建的日期范围,使用“日期”作为开始日期,使用“n”作为周期数。 所以第一个条目应该是:

pd.date_range(dt.datetime(2018,8,25), periods=10, freq='d')

(我有一个“目标”日期列表,我的目标是检查 date_range 是否包含这些目标日期)。

我试过了:

df['date_range'] = df.apply(lambda x: pd.date_range(x['date'],
                                                     x['n'],
                                                     freq='d'))

但这给出了一个 KeyError: ('date', 'occured at index date')

关于如何在不使用 for 循环的情况下执行此操作的任何想法,或者是否有更好的解决方案?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以在不创建日期范围或日期列的情况下解决您的问题。要检查 tgt 中的目标日期是否属于 df 行指定的日期范围,您可以计算日期范围的结束,然后检查 tgt 中的每个日期是否位于时间间隔的开始和结束之间。下面的代码实现了这一点,并生成与您自己答案中的列相同的“target_date”列:

    df = pd.DataFrame({'date':[dt.datetime(2018,8,25), dt.datetime(2018,7,21)],
                   'n':[10,7]})
    
    df["daterange_end"] = df.apply(lambda x: x["date"] + pd.Timedelta(days=x["n"]), axis=1)
    
    tgt = [dt.datetime(2018,8,26)]
    
    df['target_date'] = 0
    df.loc[(tgt[0] > df.date) &(tgt[0] < df.daterange_end),"target_date"] = 1
    
    print(df)
    
    #       date         n  daterange_end   target_date
    # 0 2018-08-25  10  2018-09-04      1
    # 1 2018-07-21  7   2018-07-28      0
    

    【讨论】:

      【解决方案2】:

      你应该在apply中添加axis=1

      df['date_range'] = df.apply(lambda x: pd.date_range(x['date'], x['n'], freq='d'), axis=1)
      

      【讨论】:

      • 这会引发 ValueError:值的长度与索引的长度不匹配
      • 另外你需要在 pd.date_range() 中加上 "start=" 和 "periods=",在 apply() 中加上 axis=1,像这样:df['date_range'] = df .apply( lambda x: pd.date_range(start=x['date'], period=x['n'], freq='d'), axis=1 )
      【解决方案3】:

      我想出了一个可行的解决方案(但我确信有更好的方法......)

      # define target
      tgt = [dt.datetime(2018,8,26)]
      
      # find max n
      max_n = max(df['n'])
      
      # create that many columns and increment the day
      for i in range(max_n):
          df['date_{}'.format(i)] = df['date'] + dt.timedelta(days=i)
      
      new_cols = ['date_{}'.format(n) for n in range(max_n)]
      
      # check each one and replace with a 1 if it matches the "tgt"
      df['target_date'] = 0
      for col in new_cols:
          df['target_date'] = np.where(df[col].isin(tgt),
                                1,
                                df['target_date'])
      
      # drop intermediate cols
      df = df[[i for i in df.columns if not i in new_cols]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-11
        • 2020-04-09
        • 2019-06-05
        • 2017-01-29
        • 1970-01-01
        • 1970-01-01
        • 2015-03-09
        • 2017-11-19
        相关资源
        最近更新 更多