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

如何分组交通灯连续相同状态序列统计相位时长?已尝试Counter

Got it, let's break this down. The problem with using collections.Counter here is that it only counts total occurrences of each traffic light phase, not consecutive runs of the same state—which is exactly what you need to analyze timing patterns.

Here are two straightforward solutions to group consecutive identical phases, along with code to analyze their timing:

1. Use itertools.groupby (Python's built-in tool for consecutive grouping)

itertools.groupby is perfect for this scenario because it groups consecutive elements with the same key. Since you're storing one phase per second in your deque, the length of each group directly translates to the duration (in seconds) that phase was active.

Here's how to integrate it with your existing code:

from itertools import groupby
from collections import deque
from enum import Enum
import time
import threading

# Your existing TrafficLight enum
class TrafficLightPhase(Enum):
    RED = "RED"
    YELLOW = "YELLOW"
    GREEN = "GREEN"

# Replace this with your real function to fetch the current traffic light phase
def get_current_phase_phases():
    # Simulating a traffic light cycle for demo purposes
    phase_cycle = [TrafficLightPhase.RED]*5 + [TrafficLightPhase.GREEN]*10 + [TrafficLightPhase.YELLOW]*2
    while True:
        for phase in phase_cycle:
            yield phase

# Global state for polling control and phase storage
running = True
last_phases = deque()

# Your existing polling function
def read_phases():
    phase_source = get_current_phase_phases()
    while running:
        current_phase = next(phase_source)
        last_phases.append(current_phase)
        time.sleep(1)

# Function to group consecutive phases and calculate their durations
def group_consecutive_phases(phase_queue):
    consecutive_runs = []
    # Group consecutive identical phases
    for phase, consecutive_group in groupby(phase_queue):
        # Each element in the group represents 1 second of the same phase
        duration = len(list(consecutive_group))
        consecutive_runs.append((phase, duration))
    return consecutive_runs

# Example workflow: Run polling, then analyze results
if __name__ == "__main__":
    # Start polling in a separate thread to avoid blocking
    poll_thread = threading.Thread(target=read_phases)
    poll_thread.start()
    
    # Let the polling run for 30 seconds
    time.sleep(30)
    running = False
    poll_thread.join()
    
    # Get the grouped consecutive phase runs
    phase_runs = group_consecutive_phases(last_phases)
    print("Consecutive Phase Runs:")
    for phase, duration in phase_runs:
        print(f"{phase.name}: {duration} seconds")

2. Manual Grouping (if you prefer not to use itertools)

If you want to avoid relying on itertools, you can manually iterate through the deque and track consecutive phases:

def group_consecutive_phases_manual(phase_queue):
    if not phase_queue:
        return []
    
    consecutive_runs = []
    current_phase = phase_queue[0]
    current_duration = 1
    
    # Iterate through the rest of the queue
    for phase in list(phase_queue)[1:]:
        if phase == current_phase:
            current_duration += 1
        else:
            # Save the completed run of the previous phase
            consecutive_runs.append((current_phase, current_duration))
            current_phase = phase
            current_duration = 1
    
    # Don't forget to add the last run of phases
    consecutive_runs.append((current_phase, current_duration))
    return consecutive_runs

Analyzing Timing Patterns

Once you have the consecutive runs, you can calculate useful stats like average duration per phase, total time spent in each phase, etc. Here's a quick way to do that:

from collections import defaultdict

def analyze_timing_patterns(consecutive_runs):
    phase_stats = defaultdict(lambda: {"total_time": 0, "run_count": 0})
    
    for phase, duration in consecutive_runs:
        phase_stats[phase]["total_time"] += duration
        phase_stats[phase]["run_count"] += 1
    
    # Calculate averages and format the results
    timing_patterns = {}
    for phase, stats in phase_stats.items():
        avg_duration = stats["total_time"] / stats["run_count"]
        timing_patterns[phase] = {
            "average_duration": round(avg_duration, 2),
            "total_time": stats["total_time"],
            "number_of_runs": stats["run_count"]
        }
    return timing_patterns

# Example usage
timing_stats = analyze_timing_patterns(phase_runs)
print("\nTiming Patterns:")
for phase, stats in timing_stats.items():
    print(f"{phase.name}:")
    print(f"  Average Duration: {stats['average_duration']} seconds")
    print(f"  Total Time Active: {stats['total_time']} seconds")
    print(f"  Number of Runs: {stats['number_of_runs']}")

Why Counter Didn't Work

Just to clarify: Counter counts how many times each phase appears in total (e.g., "RED appeared 15 times"), but it doesn't track if those 15 times were in a single 15-second run or 3 separate 5-second runs. That's why we need to group consecutive phases first before doing any meaningful timing analysis.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:11:08