如何计算组内值的不变发生次数

时间:2019-12-26 10:47:44

标签: python pandas run-length-encoding

假设我有一个DataFrame,如下所示:

import pandas as pd
import numpy as np

df = pd.DataFrame.from_dict({'measurement_id': np.repeat([1, 2], [30, 30]),
                             'min': np.concatenate([np.repeat([1, 2, 3, 4, 5], [6, 6, 6, 6, 6]), 
                                                    np.repeat([1, 2, 3, 4, 5], [6, 6, 6, 6, 6])]),
                             'obj': list('ABCDEF' * 10),
                             'var': [1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2,
                                     1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 2,                                                           
                                     2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2,
                                     2, 1, 1, 1, 2, 1]})

因此,有2个测量值在一分钟的间隔内测量了6个对象的var值。我想做的是创建一个列,该列将计算每个var值未更改的时间(多少分钟)。我认为可以通过适当的groupby来实现,它等效于R函数data.table::rleid,该函数创建游程类型id列并最终计算在所得列的一个值内有多少分钟。

因此,输出结果如下:

df['rleid_output'] = np.concatenate([[1] * 18, [2] * 12, [3] * 6, [4] * 18, [5] * 6])
df['expected_output'] = np.concatenate([[3] * 18, [2] * 12, [1] * 6, [3] * 18, [1] * 6])

不幸的是,我不知道如何在熊猫中做到这一点。我在创建等效的rleid以及随后获得expected_output方面都在挣扎。不管是否使用expected_output等价物,如何实现rleid的任何想法?

@Edit:要回答有关“ expected_output”的逻辑的评论,这是我脑海计算的方式:

  • 在第一次测量的第一分钟内,我们有以下objvar对:(A,1),(B,1),(C,2),(D,2), (E,2),(F,2)
  • 在测量1的第2分钟和第3分钟,这些对保持不变,因此第一次分配持续至少3分钟
  • 在第4分钟,var的{​​{1}}值变为1。至少有一对已更改,因此我们的整个分配被视为已更改,并开始了新值obj = C。同时,我们已经知道先前的分配恰好持续了3分钟,对于所有先前的行,rleid_output的值应设置为3。当前分配(expected_outputobj)是(A,1),(B,1),(C,1),(D,2),(E,2),(F,2 )。
  • 第5分钟的分配没有改变。下一组(varmeasurement_id)实际上是新的度量,因此这是我们的最后一刻,我们已经知道我们应该将min设置为具有expected_output的行中的2和(measurement_id, min) == (1, 4)的分配相同,持续2分钟。
  • 下一组行是新度量(measurement_id, min) == (1, 5)。它从分配(A,2),(B,2),(C,1),(D,1),(E,2),(F,2)开始。它会在下一分钟更改,因此我们可以将其标记为仅持续1分钟(值为(measurement_id, min) == (2, 1))的作业。
  • 下一个作业是(A,2),(B,1),(C,1),(D,1),(E,2),(F,2)并且持续3分钟-这就是为什么expected_output表示从36到53的行。
  • 最后,在测量2的第5分钟,F将expected_output = 3的值更改为2,因此我们有了新的赋值((A,2),(B,1),(C,1),(D, 1),(E,2),(F,1))仅持续1分钟,因为我们没有进一步的测量。

我希望现在更清楚

另外,最好能知道如何通过单独的作业更改来做到这一点,即,如果我们不将作业视为一个整体,而是将各个对(例如, (A,2)

@ Edit2:根据以下要求,简化了示例:

var

0 个答案:

没有答案