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

如何在Pandas groupby()中使用自定义IOU外部函数?

Hey there, let's clear up how Pandas' groupby works for your IOU-based detection grouping, and fix the implementation to get the results you want:

Pandas Groupby: Correct Return Values for IOU Detection Grouping

First: What does the by function need to return?

When you pass a function to pd.DataFrame.groupby(by=...), here's the critical detail:

  • The function is called once for each index value in your DataFrame.
  • It must return a hashable value (integer, string, tuple, etc.) that acts as the group key for that row's index.

But this won't work directly for your IOU grouping task—because calculating IOU requires comparing multiple detections within the same frame, not just evaluating a single row in isolation. So we need a two-step approach instead.

Your Solution: Frame + IOU-Based Grouping

Since you want to cluster overlapping detections in the same frame, here's how to adapt your group_detections function to work seamlessly with Pandas:

Step 1: Add a helper to assign group IDs per frame

Modify your existing function to return a unique group ID for every detection in the frame, making it easy to merge back into your original dataset:

import numpy as np
import pandas as pd

def assign_group_ids(dets_df, thresh=0.5):
    # Convert frame detections to numpy array (matches your function's input format)
    dets = dets_df[["xmin", "ymin", "xmax", "ymax", "confidence", "class", "frame_idx"]].values
    
    if dets.size == 0:
        return dets_df.assign(group_id=[])
    
    # Run your existing IOU grouping logic
    sorted_dets, groups = group_detections(dets, thresh)
    
    # Map each sorted detection to its group ID
    group_id_array = np.zeros(len(sorted_dets), dtype=int)
    for group_idx, indices in enumerate(groups):
        group_id_array[indices] = group_idx
    
    # Attach group IDs to sorted detections and merge back to original order
    sorted_dets_df = pd.DataFrame(sorted_dets, columns=dets_df.columns)
    sorted_dets_df["group_id"] = group_id_array
    
    # Merge group IDs back to the original frame's rows
    dets_df_with_group = dets_df.merge(
        sorted_dets_df[["xmin", "ymin", "xmax", "ymax", "confidence", "group_id"]],
        on=["xmin", "ymin", "xmax", "ymax", "confidence"],
        how="left"
    )
    
    return dets_df_with_group

Step 2: Apply per-frame grouping and assign group IDs

First group your data by frame_idx to isolate detections per frame, then apply the helper to add group IDs:

# Assume your raw detection data is in a DataFrame named `detections_df`
detections_df = detections_df.reset_index(drop=True)  # Ensure clean row indices

# Add IOU-based group IDs to each detection within its frame
detections_with_groups = detections_df.groupby("frame_idx", group_keys=False).apply(assign_group_ids)

# Now group by both frame and group ID to get your overlapping detection clusters
final_groups = detections_with_groups.groupby(["frame_idx", "group_id"])

Step 3: Process each group (e.g., remove duplicates)

With your final groups, you can apply your decision logic—like keeping only the highest-confidence detection per group:

def select_best_detection(group):
    # Return the detection with the highest confidence in the group
    return group.loc[group["confidence"].idxmax()]

# Get cleaned, non-duplicate detections
cleaned_detections = final_groups.apply(select_best_detection).reset_index(drop=True)

Why this works:

  1. We first isolate each frame with groupby("frame_idx"), so we only compare detections within the same video frame.
  2. Your group_detections function handles the IOU-based clustering, and we map those clusters to unique IDs.
  3. Grouping by frame_idx + group_id gives exactly the clusters of overlapping detections you need to process.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:25:05