You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中按机器分组,基于启停信号标记状态列?

多机器分组生成状态列的正确实现

问题背景

需要为包含多台机器的DataFrame生成独立的Status列:

  • Signal=1时,Status设为1(开机),状态保持1直到收到Signal=2或3(关机),Status切换为0,直到再次收到Signal=1重复上述逻辑。
  • 单机器逻辑已实现,但多机器分组处理时出现KeyError,循环拼接代码逻辑混乱,无法得到正确结果。

错误代码问题分析

  1. 错误的列索引方式:dfList = df[df['Machine']]会把Machine列的取值当作列名查找,导致KeyError,正确方式是直接获取唯一机器列表:unique_machines = df['Machine'].unique()。
  2. 函数逻辑混乱:s_gen2函数参数未使用、循环嵌套错误、引用未定义变量,且未正确为每组机器生成状态序列,拼接DataFrame的方式也不符合要求。

正确实现方案

方案一:groupby + 自定义函数(推荐)

基于单机器逻辑修改函数,使其接收单组Signal序列,通过groupby对每台机器独立计算状态:

import numpy as np
import pandas as pd

# 定义状态生成函数,接收单台机器的Signal序列
def gen_status(signal_series):
    _status = 0
    status_list = []
    for sig in signal_series:
        if _status == 0:
            if sig == 1:
                _status = 1
        else:
            if sig in (2, 3):
                _status = 0
        status_list.append(_status)
    # 返回带索引的Series,确保合并时对应原行
    return pd.Series(status_list, index=signal_series.index)

# 构造多机器测试数据
df = pd.DataFrame([])
df['Date'] = ['2020-01-01','2020-01-02','2020-01-03','2020-01-04','2020-01-05',
              '2020-01-06','2020-01-07','2020-01-08','2020-01-09','2020-01-10',
              '2020-01-11','2020-01-12','2020-01-13','2020-01-14','2020-01-15',
              '2020-01-16','2020-01-17','2020-01-18','2020-01-19','2020-01-20',
              '2020-01-01','2020-01-02','2020-01-03','2020-01-04','2020-01-05',
              '2020-01-06','2020-01-07','2020-01-08','2020-01-09','2020-01-10',
              '2020-01-11','2020-01-12','2020-01-13','2020-01-14','2020-01-15',
              '2020-01-16','2020-01-17','2020-01-18','2020-01-19','2020-01-20']

df['Machine'] = ['A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A',
                'B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B',]
df['Signal'] = [0,1,2,0,1,3,0,0,0,3,0,1,0,0,3,0,1,0,0,1,0,1,2,0,1,3,0,0,0,3,0,1,0,0,3,0,1,0,0,1]

# 为每台机器生成Status列
df['Status'] = df.groupby('Machine')['Signal'].apply(gen_status)

print(df)

方案二:循环处理每个机器分组

如果偏好循环处理,可逐个筛选机器数据、生成状态后合并:

import numpy as np
import pandas as pd

# 构造多机器测试数据(同方案一)
df = pd.DataFrame([])
df['Date'] = ['2020-01-01','2020-01-02','2020-01-03','2020-01-04','2020-01-05',
              '2020-01-06','2020-01-07','2020-01-08','2020-01-09','2020-01-10',
              '2020-01-11','2020-01-12','2020-01-13','2020-01-14','2020-01-15',
              '2020-01-16','2020-01-17','2020-01-18','2020-01-19','2020-01-20',
              '2020-01-01','2020-01-02','2020-01-03','2020-01-04','2020-01-05',
              '2020-01-06','2020-01-07','2020-01-08','2020-01-09','2020-01-10',
              '2020-01-11','2020-01-12','2020-01-13','2020-01-14','2020-01-15',
              '2020-01-16','2020-01-17','2020-01-18','2020-01-19','2020-01-20']

df['Machine'] = ['A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A',
                'B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B','B',]
df['Signal'] = [0,1,2,0,1,3,0,0,0,3,0,1,0,0,3,0,1,0,0,1,0,1,2,0,1,3,0,0,0,3,0,1,0,0,3,0,1,0,0,1]

# 获取所有唯一机器
unique_machines = df['Machine'].unique()
result_dfs = []

for machine in unique_machines:
    # 筛选当前机器的数据并复制,避免修改原DataFrame
    machine_df = df[df['Machine'] == machine].copy()
    # 生成状态序列
    _status = 0
    status_list = []
    for sig in machine_df['Signal']:
        if _status == 0:
            if sig == 1:
                _status = 1
        else:
            if sig in (2, 3):
                _status = 0
        status_list.append(_status)
    machine_df['Status'] = status_list
    result_dfs.append(machine_df)

# 合并所有机器的结果,保持原DataFrame的行顺序
final_df = pd.concat(result_dfs).loc[df.index]

print(final_df)

结果验证

两种方案生成的Status列均与期望输出一致,每台机器的状态独立计算,不会互相干扰。

内容的提问来源于stack exchange,提问作者Flint

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 20:27:05