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

Python中拆分DataFrame列内多列表并生成目标结构DataFrame及图像边界框标注方案问询

嘿,我来帮你搞定这三个需求,全部用pandas和常用工具实现,步骤清晰易懂:

首先先明确下假设的原始DataFrame结构(方便对应你的数据):

img_namebbox_label
001[[[0.0,0.0,1024.0,1024.0], [595.97,601.39,776.93,817.03]], ['Effusion', 'Effusion']]
002[[[0.0,0.0,1024.0,1024.0], [395.97,351.39,866.93,917.03]], ['Mass', 'any disease']]
需求2:生成结构化的img_name/class/xmin/ymin/xmax/ymax DataFrame

这是最常用的结构化格式,用explode完全可以实现,步骤如下:

  1. 先从嵌套列里拆分出边界框列表和标签列表:
import pandas as pd

# 假设你的原始DataFrame叫df
df['bboxes'] = df['bbox_label'].apply(lambda x: x[0])  # 提取所有边界框
df['labels'] = df['bbox_label'].apply(lambda x: x[1])  # 提取对应疾病标签
  1. 同时explode边界框和标签列,确保它们一一对应:
# explode后每一行对应一个边界框+标签,ignore_index重置索引
df_exploded = df.explode(['bboxes', 'labels'], ignore_index=True)
  1. 把嵌套的边界框拆分成单独的坐标列:
# 将bboxes的列表拆分成xmin/ymin/xmax/ymax四个列
df_exploded[['xmin', 'ymin', 'xmax', 'ymax']] = pd.DataFrame(
    df_exploded['bboxes'].tolist(), 
    index=df_exploded.index
)
  1. 整理最终的结构化DataFrame:
final_df = df_exploded[['img_name', 'labels', 'xmin', 'ymin', 'xmax', 'ymax']].rename(
    columns={'labels': 'class'}
)

最终输出就和你给出的示例结构完全一致啦!

需求1:为每种疾病生成对应新列

如果要把每种疾病作为单独的列,值是对应图像的边界框列表,我们可以基于上面的final_df来转换:

# 先按图像名称和疾病分组,把同一图像同一疾病的边界框合并成列表
grouped = final_df.groupby(['img_name', 'class'])['bboxes'].apply(list).reset_index()

# 转成宽表,每个疾病对应一列
wide_df = grouped.pivot(index='img_name', columns='class', values='bboxes').reset_index()

# 给空值填充空列表(可选)
wide_df = wide_df.fillna(value=pd.Series([[]], index=wide_df.columns))

这样每个疾病列的值就是对应图像的所有边界框列表,比如Effusion列里会是[[0.0,0.0,1024.0,1024.0], [595.97,601.39,776.93,817.03]]这样的结构。

需求3:遍历行标注边界框到图像上

用OpenCV就可以轻松实现,步骤如下:

import cv2
import os

# 替换成你的图像存储路径
img_dir = "path/to/your/image/directory"

# 遍历每个唯一的图像名称
for img_name in final_df['img_name'].unique():
    # 构建图像路径(根据你的图像后缀调整,比如jpg/png)
    img_path = os.path.join(img_dir, f"{img_name}.png")
    img = cv2.imread(img_path)
    
    if img is None:
        print(f"警告:无法读取图像 {img_name},跳过")
        continue
    
    # 获取当前图像的所有标注信息
    img_annotations = final_df[final_df['img_name'] == img_name]
    
    # 遍历每个标注画框
    for _, row in img_annotations.iterrows():
        # 把浮点坐标转成整数(OpenCV需要整数坐标)
        xmin, ymin = int(row['xmin']), int(row['ymin'])
        xmax, ymax = int(row['xmax']), int(row['ymax'])
        label = row['class']
        
        # 画绿色矩形框,厚度2
        cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2)
        # 在框上方添加标签文本
        cv2.putText(
            img, label, (xmin, ymin-10), 
            cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2
        )
    
    # 保存标注后的图像,或者直接显示
    save_path = os.path.join(img_dir, f"annotated_{img_name}.png")
    cv2.imwrite(save_path, img)
    
    # 如果需要实时显示图像,取消下面注释
    # cv2.imshow(f"Annotated: {img_name}", img)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 04:52:37