pandas-对列中具有相同值的连续行进行分组和聚合

Posted

技术标签:

【中文标题】pandas-对列中具有相同值的连续行进行分组和聚合【英文标题】:pandas- grouping and aggregating consecutive rows with same value in column 【发布时间】:2020-05-03 20:00:02 【问题描述】:

我有一个从数据库中提取的一长串日期时间范围的 pandas DataFrame,每个范围都有一个标签。对日期进行排序,使得一行的开始日期是前一行的结束日期。一个可行的例子在这里:

import pandas as pd

bins = ['start': '2020-01-12 00:00:00', 'end': '2020-01-13 00:00:00', 'label': 't3',
        'start': '2020-01-13 00:00:00', 'end': '2020-01-13 07:00:00', 'label': 't2',
        'start': '2020-01-13 07:00:00', 'end': '2020-01-13 15:30:00', 'label': 't1',
        'start': '2020-01-13 15:30:00', 'end': '2020-01-14 00:00:00', 'label': 't2',
        'start': '2020-01-14 00:00:00', 'end': '2020-01-14 07:00:00', 'label': 't2',
        'start': '2020-01-14 07:00:00', 'end': '2020-01-14 15:30:00', 'label': 't1',
        'start': '2020-01-14 15:30:00', 'end': '2020-01-15 00:00:00', 'label': 't2',
        'start': '2020-01-15 00:00:00', 'end': '2020-01-15 07:00:00', 'label': 't2',
        'start': '2020-01-15 07:00:00', 'end': '2020-01-15 15:30:00', 'label': 't1',
        'start': '2020-01-15 15:30:00', 'end': '2020-01-16 00:00:00', 'label': 't2',
        'start': '2020-01-16 00:00:00', 'end': '2020-01-16 07:00:00', 'label': 't2',
        'start': '2020-01-16 07:00:00', 'end': '2020-01-16 15:30:00', 'label': 't1',
        'start': '2020-01-16 15:30:00', 'end': '2020-01-17 00:00:00', 'label': 't2',
        'start': '2020-01-17 00:00:00', 'end': '2020-01-17 07:00:00', 'label': 't2',
        'start': '2020-01-17 07:00:00', 'end': '2020-01-17 15:30:00', 'label': 't1',
        'start': '2020-01-17 15:30:00', 'end': '2020-01-18 00:00:00', 'label': 't2',
        'start': '2020-01-18 00:00:00', 'end': '2020-01-19 00:00:00', 'label': 't2']
bins_df = pd.DataFrame(bins)

请注意,有些标签是连续重复的,例如,第 4 行和第 5 行具有相同的标签。因此,标签't2' 适用于从2020-01-13 15:30:002020-01-14 07:00:00 的范围。使用 pandas,我如何对具有相同标签的连续行进行分组/聚合,并采用最小 start 和最大 end 来组合具有相同标签的连续日期范围?

【问题讨论】:

【参考方案1】:

首先我们使用Series.shiftSeries.cumsum 为每个连续的label 值创建一个组指示符。

然后我们将groupby.aggminmax 一起使用。

label_groups = bins_df['label'].ne(bins_df['label'].shift()).cumsum()

df = (
    bins_df.groupby(label_groups).agg('start':'min', 'end':'max', 'label':'first')
           .reset_index(drop=True)
)
                 start                 end label
0  2020-01-12 00:00:00 2020-01-13 00:00:00    t3
1  2020-01-13 00:00:00 2020-01-13 07:00:00    t2
2  2020-01-13 07:00:00 2020-01-13 15:30:00    t1
3  2020-01-13 15:30:00 2020-01-14 07:00:00    t2
4  2020-01-14 07:00:00 2020-01-14 15:30:00    t1
5  2020-01-14 15:30:00 2020-01-15 07:00:00    t2
6  2020-01-15 07:00:00 2020-01-15 15:30:00    t1
7  2020-01-15 15:30:00 2020-01-16 07:00:00    t2
8  2020-01-16 07:00:00 2020-01-16 15:30:00    t1
9  2020-01-16 15:30:00 2020-01-17 07:00:00    t2
10 2020-01-17 07:00:00 2020-01-17 15:30:00    t1
11 2020-01-17 15:30:00 2020-01-19 00:00:00    t2

【讨论】:

感谢代码示例及其作用的解释。工作得很好。

以上是关于pandas-对列中具有相同值的连续行进行分组和聚合的主要内容,如果未能解决你的问题,请参考以下文章

pandas:将具有相同值的连续行分组为一组

将列中具有相同值的行合并在一起

在pandas df中,对列的值在范围内的行进行分组。

pandas 在同一张表(相同的数据框)中,如何用新名称和其他行值的总和对不同的行进行分组

Pandas GroupBy 并选择特定列中具有最小值的行

在一列中对具有相同数据的行进行分组,并将其相关数据汇总在另一列中 [ORACLE SQL]