根据30分钟的间隔计算以分钟为单位的差值?

2024-10-01 09:28:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个像

ID  | Half Hour Bucket | clock in time  | clock out time  | Rate
232 | 4/1/19 8:00 PM   | 4/1/19 7:12 PM | 4/1/19 10:45 PM | 0.54
342 | 4/1/19 8:30 PM   | 4/1/19 7:12 PM | 4/1/19 7:22 PM  | 0.23
232 | 4/1/19 7:00 PM   | 4/1/19 7:12 PM | 4/1/19 10:45 PM | 0.54

我希望我的输出是

 ID | Half Hour Bucket | clock in time  | clock out time  | Rate | Mins
232 | 4/1/19 8:00 PM   | 4/1/19 7:12 PM | 4/1/19 10:45 PM | 0.54 |
342 | 4/1/19 8:30 PM   | 4/1/19 7:12 PM | 4/1/19 7:22 PM  | 0.23 |
232 | 4/1/19 7:00 PM   | 4/1/19 7:12 PM | 4/1/19 10:45 PM | 0.54 |

其中分钟表示下班打卡时间和上班打卡时间之间的差。你知道吗

但是我只能在它对应的同一行中包含半小时bucket的分钟值。你知道吗

例如,对于ID342,它将是10分钟,10分钟将在那一排。你知道吗

但对于ID232,从打卡到打卡的时间跨度为3个小时。我只想要第一排8到830的30分钟,第三排18分钟。对于第一行中不存在的半小时bucket(如830-9或9-930)中的分钟数,我想在同一个df中创建一个新行,其中包含除半小时bucket和原始行中不存在的分钟数字段以外的所有内容的nan。你知道吗

从8点到830点的30分钟将停留在第一排,但我希望所有半小时桶的5个新行不是4/1/19 8:00 PM作为新行,只有半小时桶和从该行结转的费率。这可能吗?你知道吗

我感谢任何人抽出时间!你知道吗


Tags: inidbucketratetime时间outclock
1条回答
网友
1楼 · 发布于 2024-10-01 09:28:39

意识到我的第一个答案可能不是你想要的。这个版本,希望是。这比我最初想象的要复杂得多!你知道吗

创建数据

首先,根据问题中提供的数据框架,创建一个要使用的数据框架。结果的格式不太一样,但很容易修复,所以我把它留在这里。你知道吗

import math
import numpy as np
import pandas as pd

# Create a dataframe to work with from the data provided in the question
columns = ['id', 'half_hour_bucket', 'clock_in_time', 'clock_out_time' , 'rate']

data = [[232, '4/1/19 8:00 PM', '4/1/19 7:12 PM', '4/1/19 10:45 PM', 0.54],
        [342, '4/1/19 8:30 PM', '4/1/19 7:12 PM', '4/1/19 07:22 PM ', 0.23],
        [232, '4/1/19 7:00 PM', '4/1/19 7:12 PM', '4/1/19 10:45 PM', 0.54]]

df = pd.DataFrame(data, columns=columns)

def convert_cols_to_dt(df):
    # Convert relevant columns to datetime format
    for col in df:
        if col not in ['id', 'rate']:
            df[col] = pd.to_datetime(df[col])

    return df

df = convert_cols_to_dt(df)
# Create the mins column
df['mins'] = (df.clock_out_time - df.clock_in_time)

输出:

  id  half_hour_bucket    clock_in_time       clock_out_time      rate mins
0 232 2019-04-01 20:00:00 2019-04-01 19:12:00 2019-04-01 22:45:00 0.54 0 days 03:33:00.000000000
1 342 2019-04-01 20:30:00 2019-04-01 19:12:00 2019-04-01 19:22:00 0.23 0 days 00:10:00.000000000
2 232 2019-04-01 19:00:00 2019-04-01 19:12:00 2019-04-01 22:45:00 0.54 0 days 03:33:00.000000000

解决方案

接下来,定义一个简单的函数,返回一个长度等于min列中30分钟间隔数的列表。你知道吗

def upsample_list(x):
    multiplier = math.ceil(x.total_seconds() / (60 * 30))

    return list(range(multiplier))

并将其应用于数据帧:

df['samples'] = df.mins.apply(upsample_list)

接下来,为“samples”列中的每个列表项创建一个新行(使用Roman Pekarhere提供的答案):

s = df.apply(lambda x: pd.Series(x['samples']),axis=1).stack().reset_index(level=1, drop=True)
s.name = 'sample'

s连接到数据帧并清理额外的列:

df = df.drop('samples', axis=1).join(s, how='inner').drop('sample', axis=1)

这给了我们:

   id   half_hour_bucket    clock_in_time        clock_out_time       rate  mins
0  232  2019-04-01 20:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
0  232  2019-04-01 20:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
0  232  2019-04-01 20:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
0  232  2019-04-01 20:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
0  232  2019-04-01 20:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
0  232  2019-04-01 20:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
0  232  2019-04-01 20:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
0  232  2019-04-01 20:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
1  342  2019-04-01 20:30:00 2019-04-01 19:12:00  2019-04-01 19:22:00  0.23  00:10:00
2  232  2019-04-01 19:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
2  232  2019-04-01 19:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
2  232  2019-04-01 19:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
2  232  2019-04-01 19:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
2  232  2019-04-01 19:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
2  232  2019-04-01 19:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
2  232  2019-04-01 19:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00
2  232  2019-04-01 19:00:00 2019-04-01 19:12:00  2019-04-01 22:45:00  0.54  03:33:00

快到了!你知道吗

重置索引:

df = df.reset_index(drop=True)

将重复行设置为NaN

df = df.mask(df.duplicated())

它给出:

   id    half_hour_bucket    clock_in_time       clock_out_time      rate mins
0  232.0 2019-04-01 20:00:00 2019-04-01 19:12:00 2019-04-01 22:45:00 0.54 03:33:00
1  NaN   NaT                 NaT                 NaT                 NaN  NaT
2  NaN   NaT                 NaT                 NaT                 NaN  NaT
3  NaN   NaT                 NaT                 NaT                 NaN  NaT
4  NaN   NaT                 NaT                 NaT                 NaN  NaT
5  NaN   NaT                 NaT                 NaT                 NaN  NaT
6  NaN   NaT                 NaT                 NaT                 NaN  NaT
7  NaN   NaT                 NaT                 NaT                 NaN  NaT
8  342.0 2019-04-01 20:30:00 2019-04-01 19:12:00 2019-04-01 19:22:00 0.23 00:10:00
9  232.0 2019-04-01 19:00:00 2019-04-01 19:12:00 2019-04-01 22:45:00 0.54 03:33:00
10 NaN   NaT                 NaT                 NaT                 NaN  NaT
11 NaN   NaT                 NaT                 NaT                 NaN  NaT
12 NaN   NaT                 NaT                 NaT                 NaN  NaT
13 NaN   NaT                 NaT                 NaT                 NaN  NaT
14 NaN   NaT                 NaT                 NaT                 NaN  NaT
15 NaN   NaT                 NaT                 NaT                 NaN  NaT
16 NaN   NaT                 NaT                 NaT                 NaN  NaT

最后,向前填充half_hour_bucketrate列。你知道吗

df[['half_hour_bucket', 'rate']] = df[['half_hour_bucket', 'rate']].ffill()

最终输出:

     id     half_hour_bucket     clock_in_time        clock_out_time       rate  mins
0    232.0  2019-04-01 20:00:00  2019-04-01_19:12:00  2019-04-01_22:45:00  0.54  03:33:00
1    NaN    2019-04-01 20:00:00  NaT                  NaT                  0.54  NaT
2    NaN    2019-04-01 20:00:00  NaT                  NaT                  0.54  NaT
3    NaN    2019-04-01 20:00:00  NaT                  NaT                  0.54  NaT
4    NaN    2019-04-01 20:00:00  NaT                  NaT                  0.54  NaT
5    NaN    2019-04-01 20:00:00  NaT                  NaT                  0.54  NaT
6    NaN    2019-04-01 20:00:00  NaT                  NaT                  0.54  NaT
7    NaN    2019-04-01 20:00:00  NaT                  NaT                  0.54  NaT
8    342.0  2019-04-01 20:30:00  2019-04-01_19:12:00  2019-04-01_19:22:00  0.23  00:10:00
9    232.0  2019-04-01 19:00:00  2019-04-01_19:12:00  2019-04-01_22:45:00  0.54  03:33:00
10   NaN    2019-04-01 19:00:00  NaT                  NaT                  0.54  NaT
11   NaN    2019-04-01 19:00:00  NaT                  NaT                  0.54  NaT
12   NaN    2019-04-01 19:00:00  NaT                  NaT                  0.54  NaT
13   NaN    2019-04-01 19:00:00  NaT                  NaT                  0.54  NaT
14   NaN    2019-04-01 19:00:00  NaT                  NaT                  0.54  NaT
15   NaN    2019-04-01 19:00:00  NaT                  NaT                  0.54  NaT
16   NaN    2019-04-01 19:00:00  NaT                  NaT                  0.54  NaT

相关问题 更多 >