Python 如何统计组中未更改的值

Python 如何统计组中未更改的值,python,pandas,run-length-encoding,Python,Pandas,Run Length Encoding,假设我有一个数据帧,如下所示: 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]),

假设我有一个
数据帧
,如下所示:

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]})
因此,有两个测量值在一分钟内测量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
等价物,以及获得
预期的输出。无论是否使用等效的
rleid
如何实现
预期的\u输出

@编辑:为了回答关于“预期输出”逻辑的评论,下面是我如何在头脑中计算它的:

  • 在第一次测量的第一分钟内,我们有以下成对的
    obj
    var
    :(A,1)、(B,1)、(C,2)、(D,2)、(E,2)、(F,2)
  • 在测量1的第2分钟和第3分钟,这些对保持不变,因此第一次分配至少持续3分钟
  • 在第4分钟,对于
    obj=C
    ,var
值变为1。至少有一对已更改,因此我们的整个赋值被视为已更改,并开始新的
rleid\u输出值。同时,我们已经知道,上一次分配持续了整整3分钟,并且对于前面的所有行,
预期输出的值应设置为3。当前分配(
obj
var
)是(A,1)、(B,1)、(C,1)、(D,2)、(E,2)、(F,2)
  • 在第五分钟,作业没有改变。下一组(
    measurement\u id
    min
    )实际上是新的度量值,因此这是我们的最后一分钟,我们已经知道我们应该将
    预期输出设置为2行,其中
    (measurement\u id,min)=(1,4)
    (measurement\u id,min)=(1,5)
    ,因为分配在2分钟内是相同的
  • 下一组行是新的度量值
    (度量值id,min)=(2,1)
    。它以赋值(A,2),(B,2),(C,1),(D,1),(E,2),(F,2)开头。它会在下一分钟发生变化,因此我们可以将其标记为仅持续1分钟的分配(值为
    预期输出
  • 下一个作业是(A,2),(B,1),(C,1),(D,1),(E,2),(F,2),持续3分钟-这就是为什么36到53行的预期输出为3
  • 最后,在测量2的第5分钟,F将
    var
    值更改为2,因此我们有了新的赋值((A,2),(B,1),(C,1),(D,1),(E,2),(F,1)),只持续1分钟,因为我们没有进一步的测量
  • 我希望现在更清楚了

    另外,如果我们不把作业作为一个整体来对待,而是把每一对单独的作业来对待,例如(a,2),那么知道如何处理个人作业的变化也是很好的

    @Edit2:根据要求缩短示例,如下所示:

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

    expected\u output
    只计算
    var
    的值保持不变的分钟数。因此,您可以按如下方式获得它:如果任何
    obj
    var
    值与前一分钟相比发生了变化,您将获得
    rleid\u输出的新值。然后,
    rleid\U输出
    只计算
    min
    rleid\U输出
    的相同值范围内的唯一值。我仍然不清楚
    rleid\U输出
    预期\U输出
    应该是什么?您可以添加一个简单的示例(+演练)来说明如何计算
    rleid_输出
    预期的_输出
    。@thushv89,我编辑了这篇文章以合并详细的工作。@anky_91,根据要求,我将示例缩短为12行(我认为合并所有的怪癖是最小的)bottom@anky_91,这些问题是不同的(请注意
    rleid\u输出
    expected\u输出
    的差异)。在这里,如果任何
    obj
    measurement\u id
    var
    发生变化,则应将新的运行id分配给同一组内的所有
    obj
    。请你重新开门好吗?