提问人:Fabitosh 提问时间:10/28/2023 更新时间:10/28/2023 访问量:65
在 pandas 中聚合字符串列及时关闭
Aggregate string column close in time in pandas
问:
我正在尝试对消息进行分组,这些消息已在不久后发送。参数定义消息之间的最大持续时间,以便将它们视为块的一部分。如果将消息添加到块中,则会延长时间窗口,以便将更多消息视为块的一部分。
示例输入
日期时间 | 消息 | |
---|---|---|
0 | 2023-01-01 12:00:00 | 一个 |
1 | 2023-01-01 12:20:00 | B |
2 | 2023-01-01 12:30:00 | C |
3 | 2023-01-01 12:30:55 | D |
4 | 2023-01-01 12:31:20 | E |
5 | 2023-01-01 15:00:00 | F |
6 | 2023-01-01 15:30:30 | G |
7 | 2023-01-01 15:30:55 | H |
参数设置为 1 分钟的预期输出
日期时间 | 消息 | datetime_last | n_block | |
---|---|---|---|---|
0 | 2023-01-01 12:00:00 | 一个 | 2023-01-01 12:00:00 | 1 |
1 | 2023-01-01 12:20:00 | B | 2023-01-01 12:20:00 | 1 |
2 | 2023-01-01 12:30:00 | C\nD\nE | 2023-01-01 12:31:20 | 3 |
3 | 2023-01-01 15:00:00 | F | 2023-01-01 15:00:00 | 1 |
4 | 2023-01-01 15:30:30 | G\nH | 2023-01-01 15:30:55 | 2 |
我失败的尝试
我希望通过滚动窗口来实现这一点,该窗口将不断附加消息行。
def join_messages(x):
return '\n'.join(x)
df.rolling(window='1min', on='datetime').agg({
'datetime': ['first', 'last'],
'message': [join_messages, "count"]}) #Somehow overwrite datetime with the aggregated datetime.first.
两个聚合都因 ValueError: 而失败。invalid on specified as datetime, must be a column (of DataFrame), an Index or None
我没有看到一种干净的方法来在窗口中“访问”。此外,滚动也不适用于字符串。我的印象是,这是一条死胡同,有一种更干净的方法。datetime
输入数据和预期数据的代码段
df = pd.DataFrame({
'datetime': [pd.Timestamp('2023-01-01 12:00'),
pd.Timestamp('2023-01-01 12:20'),
pd.Timestamp('2023-01-01 12:30:00'),
pd.Timestamp('2023-01-01 12:30:55'),
pd.Timestamp('2023-01-01 12:31:20'),
pd.Timestamp('2023-01-01 15:00'),
pd.Timestamp('2023-01-01 15:30:30'),
pd.Timestamp('2023-01-01 15:30:55'),],
'message': list('ABCDEFGH')})
df_expected = pd.DataFrame({
'datetime': [pd.Timestamp('2023-01-01 12:00'),
pd.Timestamp('2023-01-01 12:20'),
pd.Timestamp('2023-01-01 12:30:00'),
pd.Timestamp('2023-01-01 15:00'),
pd.Timestamp('2023-01-01 15:30:30'),],
'message': ['A', 'B', 'C\nD\nE', 'F', 'G\nH'],
'datetime_last': [pd.Timestamp('2023-01-01 12:00'),
pd.Timestamp('2023-01-01 12:20'),
pd.Timestamp('2023-01-01 12:31:20'),
pd.Timestamp('2023-01-01 15:00'),
pd.Timestamp('2023-01-01 15:30:55'),],
'n_block': [1, 1, 3, 1, 2]})
答:
4赞
Shubham Sharma
10/28/2023
#1
比较当前和以前的日期时间值以标记差值大于 1 分钟的行,然后在标志上应用累积总和以区分不同的日期时间块。现在,按这些块对数据帧进行分组并聚合以获得结果
m = df['datetime'].diff() > pd.Timedelta(minutes=1)
df.groupby(m.cumsum(), as_index=False).agg(datetime=('datetime', 'first'),
datetime_last=('datetime', 'last'),
message=('message', '\n'.join),
n_block=('message', 'count'))
datetime datetime_last message n_block
0 2023-01-01 12:00:00 2023-01-01 12:00:00 A 1
1 2023-01-01 12:20:00 2023-01-01 12:20:00 B 1
2 2023-01-01 12:30:00 2023-01-01 12:31:20 C\nD\nE 3
3 2023-01-01 15:00:00 2023-01-01 15:00:00 F 1
4 2023-01-01 15:30:30 2023-01-01 15:30:55 G\nH 2
评论