以30分钟为间隔计算分钟差异?

时间:2019-05-10 16:02:57

标签: python python-3.x pandas data-science python-datetime

我有一个df,例如

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 |

其中分钟代表时钟输出时间和时钟输入时间之间的差异。

但是我只能在对应的同一行中包含半小时时段的分钟值。

例如对于id 342,它将是10分钟,而10分钟将在该行上。

但是对于ID 232,从时钟到时钟的输出时间跨度为3个小时。我只希望第一行中的8分钟到830的30分钟,第三行中的18分钟。对于第一行中不存在的半小时存储段(如830-9或9-930)中的分钟,我想在同一df中创建一个新行,其中包含除半小时存储段和mins字段以外的所有内容的nans原始行中不存在的分钟数。

从8-830开始的30分钟将停留在第一行,但我希望所有不是 4/1/19 8:00 PM 的半小时时段都出现5行作为只有半小时时段的新行,并且费率从该行继续。这可能吗?

我感谢任何人的宝贵时间!

1 个答案:

答案 0 :(得分: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 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

解决方案

接下来定义一个简单的函数,以返回一个长度等于def upsample_list(x): multiplier = math.ceil(x.total_seconds() / (60 * 30)) return list(range(multiplier)) 列中30分钟间隔数的列表。

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

并将其应用于数据框:

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

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

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_bucket

最后,向前填充ratedf[['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

最终输出:

repo-folder
    inventory     << likely you have this already
    roles         << this, too
    roles.galaxy  << create if you dont have it
    site.yml      << or whatever your playbook is called
    ansible.cfg   << repo-local config overriding gloabal ~/.ansible.cfg