我正在分析我们制造过程的日志文件。大多数情况下,该过程是自动运行的,但有时,工程师需要切换到手动模式进行一些更改,然后通过反应堆软件切换回自动控制。当设置为手动模式时,日志文件将该步骤记录为“man.op.”,而不是数字。下面是一个有代表性的例子。

steps = [1,2,2,'MAN.OP.','MAN.OP.',2,2,3,3,'MAN.OP.','MAN.OP.',4,4]
ser_orig = pd.Series(steps)

结果是
0           1
1           2
2           2
3     MAN.OP.
4     MAN.OP.
5           2
6           2
7           3
8           3
9     MAN.OP.
10    MAN.OP.
11          4
12          4
dtype: object

我需要发现“男人,行动”,并使他们彼此区别开来。在本例中,在检测到手动模式部分后,值为=2的两个区域应为一个区域,如下所示:
0                 1
1                 2
2                 2
3     Manual_Mode_0
4     Manual_Mode_0
5                 2
6                 2
7                 3
8                 3
9     Manual_Mode_1
10    Manual_Mode_1
11                4
12                4
dtype: object

我有代码遍历这个序列,并在将序列传递给我的对象时生成正确的结果。设定者是:
@step_series.setter
def step_series(self, ss):
    """
    On assignment, give the manual mode steps a unique name. Leave
    the steps done on recipe the same.
    """
    manual_mode = "MAN.OP."
    new_manual_mode_text = "Manual_Mode_{}"
    counter = 0
    continuous = False
    for i in ss.index:
        if continuous and ss.at[i] != manual_mode:
            continuous = False
            counter += 1

        elif not continuous and ss.at[i] == manual_mode:
            continuous = True
            ss.at[i] = new_manual_mode_text.format(str(counter))

        elif continuous and ss.at[i] == manual_mode:
            ss.at[i] = new_manual_mode_text.format(str(counter))

    self._step_series = ss

但这会遍历整个数据帧,是除了通过网络读取日志文件之外,代码中最慢的部分。
如何在不遍历整个系列的情况下检测这些非唯一部分并对其进行唯一重命名?序列是从较大的数据帧中选择的列,因此如果需要,可以添加额外的列。
对于完整的答案,我的结论是:
@step_series.setter
def step_series(self, ss):
    pd.options.mode.chained_assignment = None
    manual_mode = "MAN.OP."
    new_manual_mode_text = "Manual_Mode_{}"

    newManOp = (ss=='MAN.OP.') & (ss != ss.shift())
    ss[ss == 'MAN.OP.'] = 'Manual_Mode_' + (newManOp.cumsum()-1).astype(str)

    self._step_series = ss

最佳答案

有一种方法:

steps = [1,2,2,'MAN.OP.','MAN.OP.',2,2,3,3,'MAN.OP.','MAN.OP.',4,4]
steps = pd.Series(steps)

newManOp = (steps=='MAN.OP.') & (steps != steps.shift())
steps[steps=='MAN.OP.'] += seq.cumsum().astype(str)

>>> steps
0            1
1            2
2            2
3     MAN.OP.1
4     MAN.OP.1
5            2
6            2
7            3
8            3
9     MAN.OP.2
10    MAN.OP.2
11           4
12           4
dtype: object

要获得您列出的确切格式(从0开始而不是1,并从“man.op.”更改为“手动模式”),只需调整最后一行:
steps[steps=='MAN.OP.'] = 'Manual_Mode_' + (seq.cumsum()-1).astype(str)

>>> steps
0                 1
1                 2
2                 2
3     Manual_Mode_0
4     Manual_Mode_0
5                 2
6                 2
7                 3
8                 3
9     Manual_Mode_1
10    Manual_Mode_1
11                4
12                4
dtype: object

对于相邻的groupby,这里有a pandas enhancement request,这将使这类任务更简单。

07-24 09:52
查看更多