Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:将开始日期和结束日期拆分为开始日期和结束日期之间的所有天数_Python_Pandas_Numpy_Datetime_Data Science - Fatal编程技术网

Python:将开始日期和结束日期拆分为开始日期和结束日期之间的所有天数

Python:将开始日期和结束日期拆分为开始日期和结束日期之间的所有天数,python,pandas,numpy,datetime,data-science,Python,Pandas,Numpy,Datetime,Data Science,我有一个名为“计划休假”的数据,其中包括“开始日期”、“结束日期”、“用户ID”和“休假类型” 我希望能够创建一个新的数据框,显示每个“用户ID”的开始日期和结束日期之间的所有日期 到目前为止,我只能创建一个日期列表,该列表提供开始日期和结束日期之间的一系列日期,但我找不到一种方法来为每个“用户ID”和“休假类型”包含该列表 以下是我目前的职能: def datesplit(data): x = pd.DataFrame(columns=['Date']) for i in pl

我有一个名为“计划休假”的数据,其中包括“开始日期”、“结束日期”、“用户ID”和“休假类型”

我希望能够创建一个新的数据框,显示每个“用户ID”的开始日期和结束日期之间的所有日期

到目前为止,我只能创建一个日期列表,该列表提供开始日期和结束日期之间的一系列日期,但我找不到一种方法来为每个“用户ID”和“休假类型”包含该列表

以下是我目前的职能:

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
如果您能在这里找到解决方案,我将永远感激您!:-)

在我看来,光是日期栏是不够的。您的输出数据帧 还应包含至少一个员工ID,以了解该员工的身份 在指定的日期离开

要执行任务,请定义以下函数:

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()
此功能:

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()
  • 对于每个源行,现在收集“部分数据帧”:
    • 唯一一列是员工ID
    • 索引是开始日期和结束日期之间的日期范围
    • 给定的员工ID(单个值)实际上是 广播所有行(当前员工休假时每天)
  • 在循环之后,连接它们并转换索引(日期) 进入“常规”列
那就叫它:

result = datesplit(plannedleave)
为了测试我的代码,我将其用作源数据帧(plannedleave):

上述数据的结果为:

         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

以下是必要的循环,因此我更喜欢列表中的理解:

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)

你能创建吗?确定还需要什么其他信息吗?你可以检查。你认为在我的解决方案中使用你的样本数据公平吗?没问题,使用它。完美!非常感谢你Jezrael@DylanMcCullough-如果我的回答有用,别忘了。谢谢这对于任何数据来说都是非常重要的,因为在200行中,此解决方案的速度要快1.9倍。如果行数越多,差异就越大。这只提供了日期+一列(员工ID)。如何将所有列添加到生成的数据框中?@Vega-使用
.Index
like