вы можете сделать это, используя numpy, как показано ниже
Генерировать фиктивные данные
df = pd.DataFrame([['January 2019', 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0], ['Shift A', 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 0.0, 1.0, 1.0, 1.0], ['Shift B', 0.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 2.0, 2.0], ['Shift C', 0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], ['Shift D', 2.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0, 0.0], ['February 2019', 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, np.nan, np.nan, np.nan], ['Shift A', 0.0, 0.0, 0.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 0.0, 1.0, 1.0, 1.0, np.nan, np.nan, np.nan], ['Shift B', 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 2.0, 2.0, np.nan, np.nan, np.nan], ['Shift C', 2.0, 2.0, 2.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, np.nan, np.nan, np.nan], ['Shift D', 1.0, 1.0, 1.0, 1.0, 0.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0, 0.0, np.nan, np.nan, np.nan]], columns=('days', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'))
df
Решение
import pandas as pd
import numpy as np
## some constants
TEAMS = np.array("A,B,C,D".split(","))
TEAM_COUNT=len(TEAMS)
MAP = {1: pd.Timedelta('06:00:00'), 2:pd.Timedelta('18:00:00')}
## first transpose the table and get numpy array rows except heading
arr = df.copy().T.values[1:, :].astype(np.float)
## break array in chunk for each month and create long array
arr = np.c_[[arr[:,sec+1:sec+(TEAM_COUNT+1)]
for sec in np.arange(0,arr.shape[1], (TEAM_COUNT+1))]]
## remove data with nan and flatten the array to get one row for each team
arr = arr[~np.isnan(arr)]
## get date range from start to end dates and repeate that for team size
date_index = pd.date_range("jan-1-2019", "feb-28-2019").repeat(TEAM_COUNT)
## create dataframe
df2 = pd.DataFrame(arr, index=date_index, columns=["shift"])
## set team column for each row
df2["team"] = np.tile(TEAMS, len(df2)//len(TEAMS))
## map shift to time delta
df2 = df2[df2["shift"]!=0]
df2["shift"] = df2["shift"].map(MAP)
df2
Результат
shift team
2019-01-01 06:00:00 A
2019-01-01 18:00:00 D
2019-01-02 06:00:00 A
2019-01-02 18:00:00 B
2019-01-03 06:00:00 A
... ... ...
2019-02-26 18:00:00 D
2019-02-27 06:00:00 A
2019-02-27 18:00:00 B
2019-02-28 06:00:00 A
2019-02-28 18:00:00 B