我有一个如下所示的数据框
日期 | 姓名 | 进/出 | 时间 |
---|---|---|---|
2024-01-01 | J 博客 | 在 | 07:10 |
2024-01-01 | J博客 | 出 | 09:30 |
2024-01-01 | J博客 | 在 | 10:00 |
2024-01-01 | J 博客 | 出 | 16:00 |
2024-01-01 | H 辛普森 | 在 | 07:15 |
2024-01-01 | H 辛普森 | 出 | 16:10 |
2024-01-01 | M 辛普森 | 在 | 07:14 |
2024-01-01 | M 辛普森 | 出去 | 10:00 |
2024-01-01 | M 辛普森 | 在 | 10:15 |
2024-01-01 | M 辛普森 | 出去 | 12:00 |
2024-01-01 | M 辛普森 | 在 | 12:30 |
2024-01-01 | M 辛普森 | 出 | 17:00 |
我的最终目标是仅计算中间
IN/OUT
次的总 timedelta (total_seconds()),如突出显示的那样。预期输出如下。
日期 | 姓名 | 时间增量 |
---|---|---|
2024-01-01 | J 博客 | 1800 |
2024-01-01 | M 辛普森 | 2700 |
我还不确定从哪里开始,并且在其他地方找不到任何例子? 谢谢 Stackoverflow!
假设 Time 在一个组内排序,第一个 In/Out 总是 In,并且 In/Out 总是交替的。
to_datetime
,然后使用groupby.apply
计算diff
,忽略第一个/最后一个值(使用iloc
)和sum
“ IN" 转换为 total_seconds
之前的时间增量:
# cleanup IN/OUT format
df['In/Out'] = df['In/Out'].str.upper()
out = (df
.assign(dt=pd.to_datetime(df['Time'], format='%H:%M'))
.groupby(['Date', 'Name'])
.apply(lambda g:
g['dt'].diff().iloc[1:-1]
[g['In/Out'].eq('IN')]
.sum().total_seconds())
.reset_index(name='TimeDelta')
.query('TimeDelta>0') # optional: remove rows with null TimeDelta
)
输出:
Date Name TimeDelta
1 2024-01-01 J Bloggs 1800.0
2 2024-01-01 M Simpson 2700.0
注意。如果任何初始假设不正确,您只需预处理数据以对其进行排序并删除无效行。
我会转换您的数据帧,以便每条记录都在 X 天的人员上,并具有入时和出时时间。然后你可以计算这两次的增量。这是我的做法。
import pandas as pd
import random as rd
names=['John','Jeff']
dates=['01/01/2024','01/02/2024']
intimes=['08:00','09:00']
outtimes=['17:00','17:30']
namelist=[]
datelist=[]
inlist=[]
outlist=[]
for i in names:
for j in dates:
namelist.append(i)
datelist.append(j)
inlist.append(rd.sample(intimes,1)[0])
outlist.append(rd.sample(outtimes,1)[0])
df=pd.DataFrame()
df['Name']=namelist
df['Date']=datelist
df['In']=inlist
df['Out']=outlist
df['InDateandTime']=pd.to_datetime(df['Date']+' '+df['In'])
df['OutDateandTime']=pd.to_datetime(df['Date']+' '+df['Out'])
df['TimeDelta']=df['OutDateandTime']-df['InDateandTime']
display(df)
这是输出:
Name Date In Out InDateandTime OutDateandTime TimeDelta
0 John 01/01/2024 09:00 17:00 2024-01-01 09:00:00 2024-01-01 17:00:00 0 days 08:00:00
1 John 01/02/2024 09:00 17:00 2024-01-02 09:00:00 2024-01-02 17:00:00 0 days 08:00:00
2 Jeff 01/01/2024 09:00 17:30 2024-01-01 09:00:00 2024-01-01 17:30:00 0 days 08:30:00
3 Jeff 01/02/2024 08:00 17:30 2024-01-02 08:00:00 2024-01-02 17:30:00 0 days 09:30:00
您只需要创建一个新的数据框,将您的记录转换为每人每天的一条记录,然后将此方法应用于该数据框。您需要首先将日期和时间组合为字符串,然后使用 pd.DateTime 将它们转换为 DateTime。我已经在代码中展示了如何执行此操作。您还可以删除原来的“日期”、“输入”和“输出”列,但我保留它们是为了向您展示我到底做了什么。大部分代码只是创建一个数据集,我可以将其用作示例。