创建pd.date_range的pandas列

时间:2018-09-25 09:00:29

标签: python pandas

我有这样的数据:

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创建的日期范围,使用“ date”作为开始日期,使用“ 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 :(“日期”,“发生在索引日期”)

关于不使用for循环如何执行此操作的任何想法,还是有更好的解决方案?

3 个答案:

答案 0 :(得分:0)

您应该在axis=1中添加apply

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

答案 1 :(得分:0)

我想出了一个可行的解决方案(但是我敢肯定有更好的方法...)

# 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]]

答案 2 :(得分:0)

您可以在不创建日期范围或日期列的情况下解决问题。要检查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