在python或pandas中从文件名中提取和聚合数据

2024-09-30 10:39:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下四个列表,它们是图像的文件名,文件名的格式如下:

(疾病)-(随机患者ID)-(该患者的图像编号)

单个患者可以对每个疾病有多个图像

请参见以下各部分:

print(train_cnv_list[0:3])
print(train_dme_list[0:3])
print(train_drusen_list[0:3])
print(train_normal_list[0:3])
>>>
['CNV-9911627-77.jpeg', 'CNV-9935363-45.jpeg', 'CNV-9911627-94.jpeg']
['DME-8889850-2.jpeg', 'DME-8773471-3.jpeg', 'DME-8797076-11.jpeg']
['DRUSEN-8986660-50.jpeg', 'DRUSEN-9100857-3.jpeg', 'DRUSEN-9025088-5.jpeg']
['NORMAL-9490249-31.jpeg', 'NORMAL-9509694-5.jpeg', 'NORMAL-9504376-3.jpeg']

我想弄清楚:

  1. 每个患者/每个列表有多少张图像
  2. 四个列表中的“随机患者ID”是否有重叠?如果是这样,我可以使用groupby之类的工具将其聚合到某种报告(患者、疾病、图像数量)中吗
patient - disease1 - total number of images

        - disease2 - total number of images

        - disease3 - total number of images

其中图像总数为最大值(该患者的图像数)

我确实看到这会产生一个患者id:

train_cnv_list[0][4:11]
>>> 9911627

提前感谢您的指导


Tags: of图像患者number列表trainlistjpeg
3条回答

这里有一些函数可能会让你走上正确的轨道,但是正如@rick-supports-monica提到的,这是熊猫的一个很好的用例。您将更容易处理数据

def contains_duplicate_ids(img_list):
  patient_ids = []
  for image in img_list:
    patient_id = image.split('.')[0].split('-')[1]
    patient_ids.append(patient_id)

  if len(set(patient_ids)) == len(patient_ids):
    return False
  
  return True

def get_duplicates(img_list):
  patient_ids = []
  duplicates = []

  for image in img_list:
    patient_id = image.split('.')[0].split('-')[1]

    if patient_id in patient_ids:
      duplicates.append(patient_id)

    patient_ids.append(patient_id)

  return duplicates

def count_images(img_list):
  return len(set(img_list))

get_duplicates可以使用返回的患者ID从那里查找任何您想要的内容。我不确定我是否完全理解列表的结构。它看起来像{disease}-{patient_id}-{some_other_int}.jpg。我不知道如何在不进一步了解输入的情况下为功能添加额外的查找

我提到了pandas,但没有提到如何使用它,这里有一种方法可以将现有数据放入数据框:

import pandas as pd

# Sample data
train_cnv_list = ['CNV-9911627-77.jpeg', 'CNV-9935363-45.jpeg', 'CNV-9911628-94.jpeg', 'CNM-9911629-94.jpeg']
train_dme_list = ['DME-8889850-2.jpeg', 'DME-8773471-3.jpeg', 'DME-8797076-11.jpeg']
train_drusen_list = ['DRUSEN-8986660-50.jpeg', 'DRUSEN-9100857-3.jpeg', 'DRUSEN-9025088-5.jpeg']
train_normal_list = ['NORMAL-9490249-31.jpeg', 'NORMAL-9509694-5.jpeg', 'NORMAL-9504376-3.jpeg']

# Convert list to dataframe
def dataframe_from_list(img_list):
  df = pd.DataFrame(img_list, columns=['filename'])

  df['disease'] = [filename.split('.')[0].split('-')[0] for filename in img_list]
  df['patient_id'] = [filename.split('.')[0].split('-')[1] for filename in img_list]
  df['some_other_int'] = [filename.split('.')[0].split('-')[2] for filename in img_list]

  return df

# Generate a dataframe for each list
cnv_df = dataframe_from_list(train_cnv_list)
dme_df = dataframe_from_list(train_dme_list)
drusen_df = dataframe_from_list(train_drusen_list)
normal_df = dataframe_from_list(train_normal_list)

# or combine them into one long dataframe
df = pd.concat([cnv_df, dme_df, drusen_df, normal_df], ignore_index=True)

enter image description here

从创建定义良好的数据结构开始,使用计数器回答第一个问题

from typing import NamedTuple
from collections import Counter,defaultdict

class FileInfo(NamedTuple):
  disease:str
  patient_id:str
  image_id: str


l1 = ['CNV-9911627-77.jpeg', 'CNV-9935363-45.jpeg', 'CNV-9911627-94.jpeg']
l2 = ['DME-8889850-2.jpeg', 'DME-8773471-3.jpeg', 'DME-8797076-11.jpeg']
l3 = ['DRUSEN-8986660-50.jpeg', 'DRUSEN-9100857-3.jpeg', 'DRUSEN-9025088-5.jpeg']
l4 = ['NORMAL-9490249-31.jpeg', 'NORMAL-9509694-5.jpeg', 'NORMAL-9504376-3.jpeg']
lists = [l1,l2,l3,l4]
data_lists = []
for l in lists:
  data_lists.append([FileInfo(*f[:-5].split('-')) for f in l])
counters = []
for l in data_lists:
  counters.append(Counter(fi.patient_id for fi in l))
print(counters)
print('-----------')
cross_lists_data = dict()
for l in data_lists:
  for file_info in l:
    if file_info.patient_id not in cross_lists_data:
      cross_lists_data[file_info.patient_id] =  defaultdict(int)
    cross_lists_data[file_info.patient_id][file_info.disease] += 1  
print(cross_lists_data)
    

您可以轻松地使用熊猫:

import pandas as pd

cnv_list=['CNV-9911627-77.jpeg', 'CNV-9935363-45.jpeg', 'CNV-9911627-94.jpeg']
dme_list=['DME-8889850-2.jpeg', 'DME-8773471-3.jpeg', 'DME-8797076-11.jpeg']
dru_list=['DRUSEN-8986660-50.jpeg', 'DRUSEN-9100857-3.jpeg', 'DRUSEN-9025088-5.jpeg']
nor_list=['NORMAL-9490249-31.jpeg', 'NORMAL-9509694-5.jpeg', 'NORMAL-9504376-3.jpeg']

data =[]
data.extend(cnv_list)
data.extend(dme_list)
data.extend(dru_list)
data.extend(nor_list)

df = pd.DataFrame(data, columns=["files"])
df["files"]=df["files"].str.replace ('.jpeg','')
df=df["files"].str.split('-', expand=True).rename(columns={0:"disease",1:"PatientID",2:"pictureName"})
res = df.groupby(['PatientID','disease']).apply(lambda x: x['pictureName'].count())
print(res)

结果:

PatientID  disease
8773471    DME        1
8797076    DME        1
8889850    DME        1
8986660    DRUSEN     1
9025088    DRUSEN     1
9100857    DRUSEN     1
9490249    NORMAL     1
9504376    NORMAL     1
9509694    NORMAL     1
9911627    CNV        2
9935363    CNV        1

甚至比你现在拥有的数据帧还多

相关问题 更多 >

    热门问题