我有这样的数据:
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循环如何执行此操作的任何想法,还是有更好的解决方案?
答案 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