尝试使用 Python 将标签添加到 CSV 中的日期时间间隔分组时遇到问题
Trouble trying to add label to grouping of datetime interval in CSV using Python
如果日期时间在 15 分钟范围内,我正在尝试在我的 Pandas df 的名为 Interval 的新列中为每个 15 分钟间隔添加一个标签。
我试过 cut、qcut、strptime 和 grouper 都无济于事。
'''Basically I'd like to turn this:'''
Date
29/8/20 2:24
29/8/20 1:02
29/8/20 0:26
28/8/20 23:14
28/8/20 21:57
28/8/20 21:55
28/8/20 21:46
28/8/20 20:38
28/8/20 19:40
28/8/20 18:20
'''Into this:'''
Date Interval
29/8/20 2:24 Period 1
29/8/20 1:02 Period 2
29/8/20 0:26 Period 3
28/8/20 23:14 Period 4
28/8/20 21:57 Period 5
28/8/20 21:55 Period 5
28/8/20 21:46 Period 5
28/8/20 21:35 Period 5
28/8/20 19:40 Period 6
28/8/20 18:20 Period 7
import datetime
import pandas as pd
s_date = datetime.datetime.now()
dates = [s_date]
for days in range(1, 5):
for i in range(24 * 4):
dates.append(dates[-1] + datetime.timedelta(minutes=15))
dates.append(dates[0] + datetime.timedelta(days=days))
print(dates)
df['Interval'] = pd.cut(df['Date'], bins=dates, duplicates='drop', ordered=True, labels=labels,
right=False).cat.add_categories([i]).fillna(i)
# Save CSV File
csv_path = r'x'
df.to_csv(csv_path + 'x' + '.csv')
我觉得你解释得不是很好,但我想我知道你想要完成什么。这个问题是关于 ORDER 的。对于 .grouper
和 .cut
,ORDER 不相关。因此,您需要使用 .shift()
进行 row-wise 比较。
从本质上讲,如果下一行在 15 分钟内,这听起来像是您在尝试将同一时间段内的时间合并在一起。您可以使用 .shift()
比较一行与下一行的数据,并使用 dt.seconds > 900
计算秒数是否 > 900(即 15 分钟)。这将 return 一系列 True
或 False
。然后,只需取 .cumsum()
(当有 True
值时添加 1
,当 False
时添加 0
。最后,您可以将 dtype 更改为带有 .astype(str)
的字符串并在开头添加 'Period ' +
:
df['Date'] = pd.to_datetime(df['Date'])
df['Interval'] = 'Period ' + (((df.shift()['Date'] - df['Date']).dt.seconds > 900).cumsum() + 1).astype(str)
Out[5]:
Date Interval
0 2020-08-29 02:24:00 Period 1
1 2020-08-29 01:02:00 Period 2
2 2020-08-29 00:26:00 Period 3
3 2020-08-28 23:14:00 Period 4
4 2020-08-28 21:57:00 Period 5
5 2020-08-28 21:55:00 Period 5
6 2020-08-28 21:46:00 Period 5
7 2020-08-28 20:38:00 Period 6
8 2020-08-28 19:40:00 Period 7
9 2020-08-28 18:20:00 Period 8
如果日期时间在 15 分钟范围内,我正在尝试在我的 Pandas df 的名为 Interval 的新列中为每个 15 分钟间隔添加一个标签。 我试过 cut、qcut、strptime 和 grouper 都无济于事。
'''Basically I'd like to turn this:'''
Date
29/8/20 2:24
29/8/20 1:02
29/8/20 0:26
28/8/20 23:14
28/8/20 21:57
28/8/20 21:55
28/8/20 21:46
28/8/20 20:38
28/8/20 19:40
28/8/20 18:20
'''Into this:'''
Date Interval
29/8/20 2:24 Period 1
29/8/20 1:02 Period 2
29/8/20 0:26 Period 3
28/8/20 23:14 Period 4
28/8/20 21:57 Period 5
28/8/20 21:55 Period 5
28/8/20 21:46 Period 5
28/8/20 21:35 Period 5
28/8/20 19:40 Period 6
28/8/20 18:20 Period 7
import datetime
import pandas as pd
s_date = datetime.datetime.now()
dates = [s_date]
for days in range(1, 5):
for i in range(24 * 4):
dates.append(dates[-1] + datetime.timedelta(minutes=15))
dates.append(dates[0] + datetime.timedelta(days=days))
print(dates)
df['Interval'] = pd.cut(df['Date'], bins=dates, duplicates='drop', ordered=True, labels=labels,
right=False).cat.add_categories([i]).fillna(i)
# Save CSV File
csv_path = r'x'
df.to_csv(csv_path + 'x' + '.csv')
我觉得你解释得不是很好,但我想我知道你想要完成什么。这个问题是关于 ORDER 的。对于 .grouper
和 .cut
,ORDER 不相关。因此,您需要使用 .shift()
进行 row-wise 比较。
从本质上讲,如果下一行在 15 分钟内,这听起来像是您在尝试将同一时间段内的时间合并在一起。您可以使用 .shift()
比较一行与下一行的数据,并使用 dt.seconds > 900
计算秒数是否 > 900(即 15 分钟)。这将 return 一系列 True
或 False
。然后,只需取 .cumsum()
(当有 True
值时添加 1
,当 False
时添加 0
。最后,您可以将 dtype 更改为带有 .astype(str)
的字符串并在开头添加 'Period ' +
:
df['Date'] = pd.to_datetime(df['Date'])
df['Interval'] = 'Period ' + (((df.shift()['Date'] - df['Date']).dt.seconds > 900).cumsum() + 1).astype(str)
Out[5]:
Date Interval
0 2020-08-29 02:24:00 Period 1
1 2020-08-29 01:02:00 Period 2
2 2020-08-29 00:26:00 Period 3
3 2020-08-28 23:14:00 Period 4
4 2020-08-28 21:57:00 Period 5
5 2020-08-28 21:55:00 Period 5
6 2020-08-28 21:46:00 Period 5
7 2020-08-28 20:38:00 Period 6
8 2020-08-28 19:40:00 Period 7
9 2020-08-28 18:20:00 Period 8