Вы можете использовать .dt
accessor создать логический индекс, где для выполнения обновления, а затем внести соответствующие коррективы:
# Get the rows to split.
split_rows = (df['start_date'].dt.date != df['end_date'].dt.date)
# Get the new rows to append, adjusting the start_date to the next day.
new_rows = df[split_rows].copy()
new_rows['start_date'] = new_rows['start_date'].dt.date + pd.DateOffset(days=1)
# Adjust the end_date of the existing rows.
df.loc[split_rows, 'end_date'] = df.loc[split_rows, 'start_date'].dt.date + pd.DateOffset(days=1, seconds=-1)
# Append the new rows to the existing dataframe.
df = df.append(new_rows).sort_index().reset_index(drop=True)
Этот процесс предполагает, что между разницей между датами между start_date
и end_date
будет только один день. Если это возможно, что есть многодневные пролеты, вы можете обернуть вышеупомянутый процесс в while
цикле:
# Get the rows to split.
split_rows = (df['start_date'].dt.date != df['end_date'].dt.date)
while split_rows.any():
# Get the new rows, adjusting the start_date to the next day.
new_rows = df[split_rows].copy()
new_rows['start_date'] = new_rows['start_date'].dt.date + pd.DateOffset(days=1)
# Adjust the end_date of the existing rows.
df.loc[split_rows, 'end_date'] = df.loc[split_rows, 'start_date'].dt.date + pd.DateOffset(days=1, seconds=-1)
# Append the new rows to the existing dataframe.
df = df.append(new_rows).sort_index().reset_index(drop=True)
# Get new rows to split (if the start_date to end_date span is more than 1 day).
split_rows = (df['start_date'].dt.date != df['end_date'].dt.date)
В результате выход из ваших данных выборки:
id start_date end_date
0 1 2016-10-01 00:00:00 2016-10-01 03:00:00
1 1 2016-10-03 05:30:00 2016-10-03 06:30:00
2 2 2016-10-03 23:30:00 2016-10-03 23:59:59
3 2 2016-10-04 00:00:00 2016-10-04 01:00:00
4 1 2016-10-04 05:00:00 2016-10-04 06:00:00
5 2 2016-10-04 05:50:00 2016-10-04 06:00:00
6 1 2016-10-05 18:50:00 2016-10-05 23:59:59
7 1 2016-10-06 00:00:00 2016-10-06 02:00:00