[英]How to iterate on all days between start and end date in Python
[英]Python: Split Start and End Date into All Days Between Start and End Date
我有名为“计划休假”的数据,其中包括“开始日期”、“结束日期”、“用户 ID”和“休假类型”。
我希望能够根据“用户 ID”创建一个新的数据框,显示开始日期和结束日期之间的所有天数。
到目前为止,我只能创建一个 date_list,它提供开始日期和结束日期之间的日期范围,但我找不到为每个“用户 ID”和“离开类型”包含此日期的方法。
这是我目前的 function:
def datesplit(data):
x = pd.DataFrame(columns=['Date'])
for i in plannedleave.iterrows():
start = data['Start Date'][i]
end = data['End Date'][i]
date_list = [start + dt.timedelta(days=x) for x in range((end-start).days)]
x.append(date_list)
return x
>>> datesplit(plannedleave)
>>> Value Error: Can only Tuple-index with a MultiIndex
数据如下所示:
>>> plannedleave.dtypes
>>>
Employee ID int64
First Name object
Last Name object
Leave Type object
Start Date datetime64[ns]
End Date datetime64[ns]
dtype: object
如果您能在这里找到解决方案,我将永远感激不尽:-)
在我看来,仅Date列是不够的。 您的 output DataFrame 还应至少包含Employee ID ,以了解哪个人在给定日期休假。
要完成您的任务,请定义以下 function:
def datesplit(data):
parts = []
for idx, row in data.iterrows():
parts.append(pd.DataFrame(row['Employee ID'], columns=['Employee ID'],
index=pd.date_range(start=row['Start Date'], end=row['End Date'],
name='Date')))
return pd.concat(parts).reset_index()
这个 function:
然后调用它:
result = datesplit(plannedleave)
为了测试我的代码,我使用了 DataFrame( plannedleave )作为源代码:
Employee ID First Name Last Name Leave Type Start Date End Date
0 1001 John Brown Xxxx 2020-05-10 2020-05-15
1 1002 Betty Smith Yyyy 2020-05-18 2020-05-22
上述数据的结果是:
Date Employee ID
0 2020-05-10 1001
1 2020-05-11 1001
2 2020-05-12 1001
3 2020-05-13 1001
4 2020-05-14 1001
5 2020-05-15 1001
6 2020-05-18 1002
7 2020-05-19 1002
8 2020-05-20 1002
9 2020-05-21 1002
10 2020-05-22 1002
这是必要的循环,所以我更喜欢DataFrame.itertuples
更像DataFrame.iterrows
以提高列表理解的性能:
def datesplit(df):
df1 = df.rename(columns={'Start Date':'sdate','End Date':'edate', 'Employee ID':'ID'})
return (pd.concat([pd.Series(r.ID,pd.date_range(r.sdate, r.edate))
for r in df1.itertuples()])
.rename_axis('Date')
.reset_index(name='Employee ID'))
df = datesplit(plannedleave)
print (df)
Date Employee ID
0 2020-05-10 1001
1 2020-05-11 1001
2 2020-05-12 1001
3 2020-05-13 1001
4 2020-05-14 1001
5 2020-05-15 1001
6 2020-05-18 1002
7 2020-05-19 1002
8 2020-05-20 1002
9 2020-05-21 1002
10 2020-05-22 1002
200 行的性能:
plannedleave = pd.concat([plannedleave] * 100, ignore_index=True)
def datesplit(df):
df1 = df.rename(columns={'Start Date':'sdate','End Date':'edate', 'Employee ID':'ID'})
return (pd.concat([pd.Series(r.ID,pd.date_range(r.sdate, r.edate))
for r in df1.itertuples()])
.rename_axis('Date')
.reset_index(name='Employee ID'))
def datesplitvb(data):
parts = []
for idx, row in data.iterrows():
parts.append(pd.DataFrame(row['Employee ID'], columns=['Employee ID'],
index=pd.date_range(start=row['Start Date'], end=row['End Date'],
name='Date')))
return pd.concat(parts).reset_index()
In [152]: %timeit datesplit(plannedleave.copy())
98.2 ms ± 4.96 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [153]: %timeit datesplitvb(plannedleave.copy())
193 ms ± 30.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.