Python:函数为上一行填充一个非空值

Python: Function to fill in the previous row of a non-null value

我有一个数据集,它主要是与紧急工作人员工作的班次长度相关的时间增量值。如果满足某些条件,则轮班时间与之前的轮班长度时间相结合 ['Combined Time']

我无法获取的是 'Final Times' 列。为了不重复计算工作小时数,如果轮班合并,例如第 3 行和第 6 行,则 前一行 应显示 NaT 或 0:00 小时,任何其他行应return ['Shift Time'] 值列。

我一直在尝试编写一个我可以应用的函数,它可以获得 ['Final Times'] 列,但是在访问前一行到 'Combined Time' 值时遇到了问题。到目前为止我所做的让我得到了 2/3 但我完全迷失了部分(第二个 if 或 elif 语句)来填写 NaT/zero 部分。

def my_func(x):

    if pd.notnull(x['Combined Time']):
        return x['Combined Time']      
    else:
        return x['Shift Time']
    
df['Final Times'] = df.apply(my_func, axis=1)   

如有任何帮助,我们将不胜感激!

干杯

您可以使用 pandas where() + bfill() 为前一行填充“检查”值,因此 my_func() 将测试它以计算“最终次数” .

df['Combined Time'] = df['Combined Time'].where(
                            df['Combined Time'].bfill(limit=1).isnull(), 
                            df['Combined Time'].fillna(pd.Timedelta('0:00:00')))

修改函数:

def my_func(x):
    if pd.notnull(x['Combined Time']):
        if x['Combined Time'] == pd.Timedelta('0:00:00'):
            return pd.NaT
        else:
            return x['Combined Time']
    else:
        return x['Shift Time']

申请:

df['Final Times'] = df.apply(my_func, axis=1)
df

结果:

    Shift Time       Combined Time      Final Times
0   0 days 13:00:00  NaT                0 days 13:00:00
1   0 days 07:00:00  0 days 00:00:00    NaT
2   0 days 01:19:00  0 days 08:19:48    0 days 08:19:48
3   0 days 07:00:00  NaT                0 days 07:00:00
4   0 days 14:00:00  0 days 00:00:00    NaT
5   0 days 02:00:00  0 days 16:00:00    0 days 16:00:00

加载数据:
(请将您的数据和格式粘贴为代码而不是屏幕截图)

df = pd.DataFrame({'Shift Time': [pd.Timedelta('13:00:00'), 
                             pd.Timedelta('7:00:00'),
                             pd.Timedelta('1:19:00'),
                             pd.Timedelta('7:00:00'),
                             pd.Timedelta('14:00:00'),
                             pd.Timedelta('2:00:00')],
                  'Combined Time': [np.nan, np.nan, 
                               pd.Timedelta('8:19:48'), 
                               np.nan, 
                               np.nan, 
                               pd.Timedelta('16:00:00')],
                  'Final Times': np.nan * 6})