【问题标题】:How to number each consecutive night in a pandas dataframe using python如何使用python在熊猫数据框中对每个连续的夜晚进行编号
【发布时间】:2021-07-29 05:13:56
【问题描述】:

在 Python 3x 中,我有一些已填充的列表,我已将它们放入以“ID”和“时间”为列的 pandas 数据框中:

import pandas as pd
df = pd.DataFrame({'ID': ID, 'UTCTime': UTCTime})
print(df)

ID              UTCTime
3    4  2021-04-03 21:56:53
4    5  2021-04-03 21:56:55
5    6  2021-04-03 21:56:57
6    7  2021-04-03 22:00:07
7    8  2021-04-03 22:00:09
8    9  2021-04-03 22:00:11
9   10  2021-04-03 22:05:08
10  11  2021-04-03 22:05:10
... 

这就是数据的样子,持续了几个月。时间戳之间的间隔不相等。

但现在我想添加一个额外的列“NightID”并识别每个连续的夜晚并给它一个唯一的编号。因此,选择 18:00 到 06:00 之间的时间,将其称为“1”,然后到第二天晚上,将其称为“2”,以此类推整个数据集。 所以它看起来像这样:

ID  UTCTime  nightID
1   27/04/2021 18:00    1
2   27/04/2021 21:05    1
3   28/04/2021 01:50    1
4   28/04/2021 02:25    1
5   28/04/2021 02:30    1
6   28/04/2021 05:59    1
7   28/04/2021 15:00    0
8   28/04/2021 18:00    2
9   28/04/2021 19:40    2
10  28/04/2021 23:50    2
11  29/04/2021 00:05    2
12  29/04/2021 00:35    2
13  29/04/2021 01:55    2
14  29/04/2021 02:30    2
15  29/04/2021 05:59    2
16  29/04/2021 06:01    0
17  29/04/2021 18:01    3
18  29/04/2021 22:30    3
19  29/04/2021 22:35    3

知道如何做到这一点吗?

非常感谢所有帮助!

亲切的问候,马丁

【问题讨论】:

  • 应该如何考虑7:00这样的时间?它是第二天晚上的一部分还是应该被排除在外而不是编号?如果 5:59 是当前晚上,是第二天 6:00 还是当前晚上的一部分?
  • 您好,Henry,感谢您抽出宝贵时间查看我的问题。是的,可以排除这一天。 05:59:59 是晚上,06:00:00 是白天。 17:59:59 是白天,18:00:00 是晚上。
  • 额外信息:可以排除这一天或将其赋值为 0

标签: python pandas indexing


【解决方案1】:

使用shift 查找日期变化并使用cumsum 创建nightID。

import pandas as pd
df = pd.DataFrame({'ID': range(8), 'UTCTime': pd.to_datetime(['2021-04-03 14:56:53',
                                                              '2021-04-03 18:00:00',
                                                              '2021-04-03 18:56:53',
                                                              '2021-04-04 05:03:24',
                                                              '2021-04-04 06:00:00',
                                                              '2021-04-04 06:10:09',
                                                              '2021-04-04 17:10:34',
                                                              '2021-04-04 18:20:03'])})

time_shifted = df['UTCTime'] + datetime.timedelta(hours = 6)
is_night = (time_shifted.dt.hour < 12)
night_id = (time_shifted.dt.date != time_shifted.dt.date.shift(1)) & (time_shifted.dt.date.shift(1).notna())
night_id = night_id.cumsum()
df['nightID'] = 0
df.loc[is_night, 'nightID'] = night_id
    ID  UTCTime             nightID
0   0   2021-04-03 14:56:53 0
1   1   2021-04-03 18:00:00 1
2   2   2021-04-03 18:56:53 1
3   3   2021-04-04 05:03:24 1
4   4   2021-04-04 06:00:00 0
5   5   2021-04-04 06:10:09 0
6   6   2021-04-04 17:10:34 0
7   7   2021-04-04 18:20:03 2

【讨论】:

  • 嗨 Z Li,感谢您努力回答我的问题。我试过你的代码。它工作正常,但现在夜晚会随着日期的增加而变化。
  • 我编辑了我最初的问题,希望能更好地解释问题
  • @Z Li 这非常有用并且可以解决问题。非常感谢!
【解决方案2】:

让我们尝试这样的事情:

# Ensure UTCTime is DateTime
df['UTCTime'] = pd.to_datetime(df['UTCTime'])

# Mask To get Times We're interested in
m = (18 <= df['UTCTime'].dt.hour) | (df['UTCTime'].dt.hour < 6)
# Shift Values Between Start and End Time so that they appear on the same date
# (Eg. 5 am becomes 11 pm the previous day)
df['OffsetTime'] = df['UTCTime'] - pd.Timedelta(hours=6)
# Create Group For Each Day
df['NightId'] = np.where(
    m, df['OffsetTime'].dt.date.astype('category').cat.codes + 1, 0
)

print(df)

来源:

ID UTC时间 3 4 2021-04-03 18:00 4 5 2021-04-03 21:05 5 6 2021-04-04 05:59 6 7 2021-04-04 15:00 7 8 2021-04-04 18:00 8 9 2021-04-04 19:40

输出:

ID UTCTime OffsetTime NightId 3 4 2021-04-03 18:00:00 2021-04-03 12:00:00 1 4 5 2021-04-03 21:05:00 2021-04-03 15:05:00 1 5 6 2021-04-04 05:59:00 2021-04-03 23:59:00 1 6 7 2021-04-04 15:00:00 2021-04-04 09:00:00 0 7 8 2021-04-04 18:00:00 2021-04-04 12:00:00 2 8 9 2021-04-04 19:40:00 2021-04-04 13:40:00 2

没有额外的变量和列

df['NightId'] = np.where(
    (18 <= df['UTCTime'].dt.hour) | (df['UTCTime'].dt.hour < 6),
    (df['UTCTime'] - pd.Timedelta(hours=6)).dt.date.astype('category').cat.codes + 1,
    0
)
ID UTCTime NightId 3 4 2021-04-03 18:00:00 1 4 5 2021-04-03 21:05:00 1 5 6 2021-04-04 05:59:00 1 6 7 2021-04-04 15:00:00 0 7 8 2021-04-04 18:00:00 2 8 9 2021-04-04 19:40:00 2

【讨论】:

  • @Henry Ecke 非常有用并且可以解决问题。我也很欣赏你添加的 cmets。当我导入 NumPy 时,它工作得很好!非常感谢!
猜你喜欢
  • 2021-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 1970-01-01
  • 2017-04-09
  • 2019-08-05
相关资源
最近更新 更多