【问题标题】:Split rows in multiple rows based on variable time condition根据可变时间条件将行拆分为多行
【发布时间】:2021-02-19 14:23:23
【问题描述】:

我有这样的班次:

  Shift horaIni     horaFin
0   A   00:00:00    08:00:00
1   B   08:00:00    16:00:00
2   C   16:00:00    23:59:59

下面的数据框是我的输入,我需要根据班次拆分一行。因此,如果一行在第 1 天的班次 A 中有一个 INITRA,在第 3 天的班次 C 中有一个 FINTRA,我需要将其拆分为具有所有班次和日期的多行。重复该行的所有其他列值。

关注第 1 行(索引 0)

   col1 col2       INITRA               FINTRA     col3 col4 col5
0   C2  Y5  2021-02-15 22:07:00 2021-02-17 05:26:42 AA  AL  111871
1   X12 Y1  2021-02-15 22:00:36 2021-02-15 22:02:40 AA  AL  111863
2   S44 S1  2021-02-15 21:30:39 2021-02-15 21:44:51 AA  AL  111863
3   Z1  J7  2021-02-15 21:26:28 2021-02-15 21:28:00 AA  AL  111863
4   O9  H5  2021-02-15 21:14:29 2021-02-15 21:15:40 AA  AL  111863
5   O7  H8  2021-02-15 20:45:31 2021-02-15 20:46:39 AA  AL  111863
6   H8  Y5  2021-02-15 20:37:05 2021-02-15 20:38:10 AA  AL  111863
7   C2  Q1  2021-02-15 20:15:49 2021-02-15 20:27:22 AA  AL  111863

下面的预期结果

  col1 col2 col3 col4  col5  dateIni      dateFin   horaIni      horaFin  Shift
0   C2  Y5  AA  AL  111871  2021-02-15  2021-02-15  22:07:00    23:59:59    C
1   C2  Y5  AA  AL  111871  2021-02-16  2021-02-16  00:00:00    08:00:00    A
2   C2  Y5  AA  AL  111871  2021-02-16  2021-02-16  08:00:00    16:00:00    B
3   C2  Y5  AA  AL  111871  2021-02-16  2021-02-16  16:00:00    23:59:59    C
4   C2  Y5  AA  AL  111871  2021-02-17  2021-02-17  00:00:00    05:26:42    A
5   X12 Y1  AA  AL  111863  2021-02-15  2021-02-15  22:00:36    22:02:40    C
6   S44 S1  AA  AL  111863  2021-02-15  2021-02-15  21:30:39    21:44:51    C
7   Z1  J7  AA  AL  111863  2021-02-15  2021-02-15  21:26:28    21:28:00    C
8   O9  H5  AA  AL  111863  2021-02-15  2021-02-15  21:14:29    21:15:40    C
9   O7  H8  AA  AL  111863  2021-02-15  2021-02-15  20:45:31    20:46:39    C
10  H8  Y5  AA  AL  111863  2021-02-15  2021-02-15  20:37:05    20:38:10    C
11  C2  Q1  AA  AL  111863  2021-02-15  2021-02-15  20:15:49    20:27:22    C

我能够解决在同一天连续轮班发生的 INITRA 和 FINTRA 问题,但是当我有更大的差异时,我似乎无法解决它。我的数据库有数十万行。

我已经坚持了一段时间了。我很感激任何帮助。提前谢谢你

【问题讨论】:

    标签: python pandas dataframe datetime rows


    【解决方案1】:
    from pprint import pprint
    initra = ['2021-02-15 22:07:00','2021-02-15 22:00:36']
    fintra = ['2021-02-17 05:26:42','2021-02-15 22:02:40']
    
    dateIni = [t[:-9] for t in initra]
    horaIni = [t[11:] for t in initra]
    dateFin = [t[:-9] for t in fintra]
    horaFin = [t[11:] for t in fintra]
    
    updatedDatabase = [[],[],[],[],[]]
    
    def generate_database(enterdate,exitdate,entertime,exittime,Shift):
        updatedDatabase[0].append(enterdate)
        updatedDatabase[1].append(exitdate) 
        updatedDatabase[2].append(entertime)
        updatedDatabase[3].append(exittime) 
        updatedDatabase[4].append(Shift)
    
    def generate_shift(dateIni,dateFin,horaIni,horaFin):
        for index,elem in enumerate(dateIni):
            enterdate = dateIni[index]
            exitdate = dateFin[index]
            entertime = horaIni[index]
            exittime = horaFin[index]
            count = abs(int(dateIni[index][8:]) - int(dateFin[index][8:]))
            count = count if count != 0 else 1
            for h in range(3*count):
    
                if enterdate == exitdate: 
                    if int(entertime[:-6]) >= 0 and int(entertime[:-6]) < 8:
                        if int(exittime[:-6]) > 8:
                            generate_database(enterdate,enterdate,entertime,'08:00:00','A')
                            entertime = '08:00:00'
                        else:
                            generate_database(enterdate,enterdate,entertime,exittime,'A')
                            break
    
                    elif int(entertime[:-6]) >= 8 and int(entertime[:-6]) < 16:
                        if int(exittime[:-6])> 16:
                            generate_database(enterdate,enterdate,entertime,'16:00:00','B')
                            entertime = '16:00:00'
                        else:
                            generate_database(enterdate,enterdate,entertime,exittime,'B')
                            break
                    elif int(entertime[:-6]) >= 16 and int(entertime[:-6]) < 24:
                        if int(exittime[:-6])> 24:
                            generate_database(enterdate,enterdate,entertime,'16:00:00','B')
                            entertime = exittime
                        else:
                            generate_database(enterdate,enterdate,entertime,exittime,'B')
                            break
    
                else:
                    if int(entertime[:-6]) >= 0 and int(entertime[:-6]) < 8:
                        generate_database(enterdate,enterdate,entertime,'08:00:00','A')
                        entertime = '08:00:00'
    
                    elif int(entertime[:-6]) >= 8 and int(entertime[:-6]) < 16:
                        generate_database(enterdate,enterdate,entertime,'16:00:00','B')
                        entertime = '16:00:00'
    
                    elif int(entertime[:-6]) >= 16 and int(entertime[:-6]) < 24:
                        generate_database(enterdate,enterdate,entertime,'23:59:59','C')
                        x = str(int(enterdate.replace('-','')) + 1)
                        enterdate = x[:-4]+'-'+x[4:-2]+'-'+x[6:]
                        entertime = '00:00:00'
    
    
    generate_shift(dateIni,dateFin,horaIni,horaFin)
    
    for i in range(len(updatedDatabase[0])):
        print(updatedDatabase[0][i],updatedDatabase[1][i],updatedDatabase[2][i],updatedDatabase[3][i],updatedDatabase[4][i])
    

    【讨论】:

    • 考虑到 INITRA 和 FINTRA 的倒数,您刚刚分配了班次。当我的 INITRA 和 FINTRA 经历多次轮班时,我需要将一行拆分为多行。
    • 这行得通 :),现在您只需将数据库更新到您的终点
    • 这几乎可行,但我能够用你的想法构建一些东西。非常感谢你的帮助。只是一个观察:而不是这样做: x = str(int(enterdate.replace('-','')) + 1) enterdate = x[:-4]+'-'+x[4:-2] +'-'+x[6:] 最好使用 .datetime + timedelta ,因为它可以在您使用一个多月时解决问题。再次感谢您的帮助
    猜你喜欢
    • 2016-12-01
    • 1970-01-01
    • 2019-04-06
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    相关资源
    最近更新 更多