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

时间:2020-06-16 06:53:48

标签: python pandas numpy datetime data-science

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

我希望能够创建一个新的数据框,以按照“用户ID”显示从开始日期到结束日期的所有日期。

到目前为止,我只能创建一个date_list,它提供开始日期和结束日期之间的日期范围,但是我找不到一种为每个“用户ID”和“离开类型”包括此日期的方法。 / p>

这是我当前的功能:

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

如果您能在这里找到解决方案,我将不胜感激! :-)

2 个答案:

答案 0 :(得分:0)

在我看来,仅 Date 列是不够的。您的输出DataFrame 还应至少包含 Employee 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()

此功能:

  • 对于每个源行,现在收集“部分DataFrames”:
    • 唯一的列是 Employee ID
    • 索引是开始日期和结束日期之间的日期范围,
    • 给定的雇员ID (一个单个值)实际上是 广播所有行(当前雇员请假的每一天)。
  • 循环后,将它们连接起来并转换索引( Date ) 进入“常规”列。

然后称呼它:

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

答案 1 :(得分:0)

这是必需的循环,因此在列表理解中,我更喜欢DataFrame.itertuplesDataFrame.iterrows类似于performance

Private Sub SaveFileData_Click()

Dim DateB1 As Date
DateB1 = B1.Value
Sheets("DATAX").Range("N2") = DateB1

Dim DateE1 As Date
DateE1 = E1.Value
Sheets("DATAX").Range("O2") = DateE1

Unload Me
End Sub

具有200行的性能:

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