【问题标题】:How to slice rows in between time intervals on a case by case basis python如何根据具体情况在时间间隔之间切片python
【发布时间】:2019-10-24 00:23:44
【问题描述】:

我想在 df2 中的时间间隔 StartTimeEndTime 之间的时间间隔内分割 df1 中的行(按列中的值 Group_Iddf2)。然后将多个切片连接在一起,因为它们具有相同的格式。

所以这是df1

      Timestamp           Group_Id      Data
2013-10-20 00:00:05.143    11           14
2013-10-21 00:05:10.377    11           15
2013-10-22 14:22:15.501    11           19
                   ...
2019-02-05 00:00:05.743    101          21
2019-02-10 00:00:10.407    101          33

df2:

EndTime          StartTime             Group_Id
27/10/13 16:08   20/10/13 16:08          11
03/12/16 16:11   26/11/16 16:11          2
24/10/14 12:08   17/10/14 12:08          11
04/07/17 08:00   27/06/17 08:00          100
03/04/13 14:10   27/03/13 14:10          26
15/11/18 17:00   08/11/18 17:00          46
11/02/19 00:20   04/02/19 00:20          101

第一步: 我们从Group_Id,df2 列的第一行开始:11

第二步: 复制并粘贴 df1 中位于 EndTimeStartTime 之间的对应行,用于 Group_Id==11

第三步: 连接Group_Id(df2)中每个的所有切片子集

希望最终数据集df3 看起来像这样:

Group_Id EndTime         StartTime      Timestamp                 Data
11       27/10/13 16:08  20/10/13 16:08 2013-10-20 20:00:05.143   14
11       27/10/13 16:08  20/10/13 16:08 2013-10-21 00:05:10.377   15
11       27/10/13 16:08  20/10/13 16:08 2013-10-22 14:22:15.501   19
                             ...
101      11/02/19 00:20  04/02/19 00:20 2019-02-05 00:00:05.743   21
101      11/02/19 00:20  04/02/19 00:20 2019-02-10 00:00:10.407   33
                             ...

一个错误的伪代码:

for i in df2['Group_Id']:
  if i = df1['Group_Id'],
  dfxx = df1[(df1['Timestamp'] <= df2.loc[i, 'EndTime']) & df1['Timestamp'] > (df2.loc['EndTime'] - dt.timedelta(days=7)])                                                                   
  pd.concat(dfxx for all i)
  i = i+1 

希望这有助于更好地说明问题。

【问题讨论】:

  • df1.Timestamp 2013-10-20 00:00:05.14327/10/13 16:08 20/10/13 16:08 之外。为什么会出现在输出中?
  • @Andy L. 谢谢这是一个错字,我刚刚修正了它

标签: python pandas datetime


【解决方案1】:

df1.Timestamp 转换为日期时间。合并Group_Id。从startenddf3 创建IntervalIndex。使用 listcomp 创建真/假掩码 m 和切片 df3

df1.Timestamp = pd.to_datetime(df1.Timestamp)
df3 = df2.merge(df1, on='Group_Id')
iix = pd.IntervalIndex.from_tuples([*df3[['StartTime','EndTime']].apply(pd.to_datetime, dayfirst=True).to_records(index=False)], 
                                   closed='both')
m = [x in iix[i] for i, x in enumerate(df3.Timestamp)]

df3.loc[m]

Out[494]:
          EndTime       StartTime  Group_Id               Timestamp  Data
0  27/10/13 16:08  20/10/13 16:08        11 2013-10-20 20:00:05.143    14
1  27/10/13 16:08  20/10/13 16:08        11 2013-10-21 00:05:10.377    15
2  27/10/13 16:08  20/10/13 16:08        11 2013-10-22 14:22:15.501    19
6  11/02/19 00:20  04/02/19 00:20       101 2019-02-05 00:00:05.743    21
7  11/02/19 00:20  04/02/19 00:20       101 2019-02-10 00:00:10.407    33

【讨论】:

  • 谢谢,但我不知道为什么输出是空的,只有标题
  • @nilsinelabore:您的真实数据集中有一些不寻常的东西不在您提供的样本数据中。您可以执行上面的逐行命令并检查每一行的结果,以查看它在真实数据集上的失败位置。
  • 谢谢我现在可以运行它,但似乎Timestamp 没有被StartTime EndTime 过滤
  • @nilsinelabore: 在你的真实数据集上创建iix 后,检查它是否是 dtype IntervalIndex,其值来自df3.StartTimedf3.EndTime(注意:df3 是结果来自 merge) 并检查 df1.Timestamp 是 dtype datetime
【解决方案2】:

您应该能够根据您的示例通过合并来完成此操作。

df1.merge(df2,on='Group_Id',how='left')

【讨论】:

  • 谢谢,我认为它不会起作用,因为Group_Id 不是唯一的..
猜你喜欢
  • 2014-02-17
  • 2020-04-20
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
  • 2013-12-09
  • 1970-01-01
相关资源
最近更新 更多