python - Pandas groupby 可变时间间隔

标签 python pandas dataframe pandas-groupby

我正在努力寻找使用某些约束对 DataFrame 进行分组的正确方法。我有以下数据框:

           start_dt  machine     benchmark      value1  value2  value3
2021-06-07 07:32:01  A           bench1         0       0       0
2021-06-07 07:32:37  A           bench1         0       0       0
2021-06-07 07:33:13  A           bench1         0       0       0
2021-06-07 07:33:49  A           bench1         0       0       0
2021-06-07 07:34:26  A           bench1         0       0       0
2021-06-07 08:30:26  A           bench1         0       0       10
2021-06-07 11:12:21  A           bench1         0       0       6
2021-06-07 12:05:21  A           bench1         1       0       10
2021-06-17 12:28:57  A           bench2         0       0       0
2021-06-17 12:29:29  A           bench2         0       0       0
2021-06-17 12:33:09  A           bench2         3       0       1
2021-06-17 12:33:48  A           bench2         3       0       1
2021-06-17 12:35:17  A           bench2         0       0       0

我想根据机器、基准和 start_dt 列进行分组。但是,它对 start_dt 列有一些限制。 start_dt 组标准必须位于 1h block 上。我尝试了以下命令:

df.groupby(["machine", "benchmark", pd.Grouper(key="start_dt", freq="1h", sort=True, origin="start")]).sum()

但是,它会根据所有基准测试的第一个日期时间对数据帧进行分组,我不希望这样。我想要的是类似下面的内容,其中 end_dt 是 start_dt + 1h。

machine benchmark          start_dt               end_dt   value1  value2  value3              
A       bench1  2021-06-07 07:32:01  2021-06-07 08:32:01   0          0    10
                2021-06-07 11:12:21  2021-06-07 12:12:21   1          0    16
        bench2  2021-06-17 12:28:57  2021-06-17 13:28:57   6          0    2

例如机器A和benchmark bench1至少有两个时间间隔

2021-06-07 07:32:01 2021-06-07 08:32:01

2021-06-07 11:12:21 2021-06-07 12:12:21

但中间没有任何内容,因此我想保持时间间隔,因为它们出现在列上,而不是 pandas Grouper 给我的时间间隔。可能吗?

编辑:

  • 时间戳是唯一的

最佳答案

是的,这是可能的,您只需要创建一个自定义分组函数来处理用例的不一致性。在下面的解决方案中,我首先创建一个新列 end_dt,稍后我们将其用作最内层的分组索引。为了创建这个列,我们正在调用函数 get_end_times() 使用 start_dt 列,该列将获取每个组 (machine/benchmark 组合)并调用 run_calc() 内部函数。此函数使用传递给函数的数据帧切片中的第一个 start_dt 来确定设置端点的位置(1 小时后)。然后它检查哪些元素落在该范围内并返回 end_dt 的集合,该集合将被重新分配给调用内部函数的组。这将迭代,直到所有 start_dt 值都被分配了一个 end_dt 值(通过 (~f).all() 检查)。完整实现见下文:

def run_calc(x):

    i = (x - x.iloc[0]).dt.total_seconds()>3600

    x[~i] = x.iloc[0] + np.timedelta64(1, 'h')

    return x, i

def get_end_times(group):

    f = pd.Series([True]*len(group), index=group.index)

    iterate = True

    while iterate:
        new, f = run_calc(group[f])
        group[(~f).index] = new
        if (~f).all(): iterate = False

    return group

df['end_dt'] = df.groupby(['machine','benchmark'])['start_dt'].transform(get_end_times)

df.groupby(['machine','benchmark','end_dt']).agg({'start_dt': 'first', 'value1': 'sum', 'value2': 'sum', 'value3': 'sum'}) \
    .reset_index().set_index(['machine','benchmark','start_dt','end_dt'])

产量:

                                                           value1  value2  \
machine benchmark start_dt            end_dt                                
A       bench1    2021-06-07 07:32:01 2021-06-07 08:32:01       0       0   
                  2021-06-07 11:12:21 2021-06-07 12:12:21       1       0   
        bench2    2021-06-17 12:28:57 2021-06-17 13:28:57       6       0   

                                                           value3  
machine benchmark start_dt            end_dt                       
A       bench1    2021-06-07 07:32:01 2021-06-07 08:32:01      10  
                  2021-06-07 11:12:21 2021-06-07 12:12:21      16  
        bench2    2021-06-17 12:28:57 2021-06-17 13:28:57       2  

关于python - Pandas groupby 可变时间间隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68154495/

相关文章:

python-3.x - Pandas 样式 applymap 使用 lambda 函数突出显示重复项

python - 错误 'AttributeError: ' DataFrameGroupBy'对象没有属性'而数据帧上的 groupby 功能

python - 合并 Pandas 列(一对多)

python - 上传文件时无法通过 'tuple' 对象没有属性 'startswith' 错误

python - 使用包含时间序列的多索引对 Pandas 数据帧进行重采样

sql - 基于不同 Pandas DataFrame 条件查找的返回值

python - 使用 pandas 从世界银行 API 获取数据

python-2.7 - 使用 python 和 matplotlib 的时间线条形图

r - 在 A 列中查找大于 0 的第一个值的位置,并在 B 列中的该位置返回值

python - 如何在 Pandas 的 groupby 对象中获取组数?