我有一个包含3列的csv文件,其中包含图像数据集。第1列名称为``ID'',其中ID代表患者ID,第2列和第3列分别代表数据集的侧面和标签。我想将此数据帧拆分为根据患者ID进行测试和训练集,在这两个集合中都不会重复患者ID。我的意思是,测试集中不会出现火车ID。使用下面的代码
# Defining a function for spliting dataframe into train and test
df_Datacopy = df_Data.copy() # copy the df
#df_Datacopy= df_Datacopy.sort_values(by=['ID'])
df_Datacopy = df_Datacopy.sample(frac=1)
train_df = df_Datacopy.sample(frac=0.80, random_state=0) # train spliting size 80%
# sorted according to ID
train_df= train_df.sort_values(by=['ID'])
# test split and by removing train index
test_df = df_Datacopy.drop(train_df.index)
# sorted according to ID
test_df= test_df.sort_values(by=['ID'])
u1 = np.unique(train_df['ID'])
u2 = np.unique(test_df['ID'])
print(set(u1).union(set(u2)))
我试图拆分测试集和训练集,但是问题是我看到测试集和训练集中都存在一些ID。如果我得到包括代码示例在内的一些帮助,这将对我有很大的帮助。
答案 0 :(得分:0)
我建议使用布尔掩码过滤数据集。 如果您想分割50/50,则可能需要检查ID是偶数还是不均匀。
由于您没有提供任何建议的数据或我建议的分割条件的详细信息,所以
train_df= df[df.ID % 2 == 0]
test_df = df[df.ID % 2 != 0]
这是您想要实现的目标吗? 如果无法提供,则可能会提供有关所需结果的更多信息。
答案 1 :(得分:0)
因此,我建议为此使用简单的 Python 列表作为首选且更简单的方法。自从您开始使用 Pandas,我将提供一种使用 Pandas 方法来实现类似但可能产生更糟结果的方法。
whole_dataset_list =df_copy.to_numpy().tolist()
patientid_list =df['ID'].to_numpy().tolist()
patientid_set =list(set(patientid_list))
import random as rand
rand.shuffle(patientid_set)
#Change the numbers as to represent a 80% slice of your dataset/10/10 respectively
train_set_by_patientID = patientid_set[0:800] # 80
val_set_by_patientID = patientid_set[800:900] # 10
test_set_by_patientID = patientid_set[1000:] # 10
拆分这些列表后,您可以使用它们来获得最终的训练/测试/验证拆分。
for i in range(len(wholeDataset_list)):
curr_pt_id = wholeDataset_list[i]
if(curr_pt_id in train_set_by_patientID):
train_set.append(wholeDataset_list[i])
elif(curr_pt_id in val_set_by_patientID):
val_set.append(wholeDataset_list[i])
elif(curr_pt_id in test_set_by_patientID):
test_set.append(wholeDataset_list[i])
else:
raise RuntimeError("Whole dataset does not contain given i ")
最后,如果您愿意,您可以回到数据框:
train_df = pd.DataFrame(train_set, columns=df_copy.columns)
val_df = pd.DataFrame(val_set, columns=df_copy.columns)
test_df = pd.DataFrame(test_set, columns=df_copy.columns)
这里的 sop_uid 是唯一索引。我正在使用训练/验证/测试拆分而不是训练/测试拆分,但可以轻松更改。
dff.sort_values(by="patient_id", axis=0, inplace=True)
count_study = dff.groupby_agg(by = 'patient_id', agg='count', agg_column_name='sop_uid', new_column_name="count_instances")
df_Datacopy = dict_dff
train_df = df_Datacopy.sample(frac=0.90, weights='count_study', random_state=0) # train spliting size 90%
train_df= train_df.sort_values(by=['count_instances'], ascending = False)
# test split and by removing train index
test_df = df_Datacopy.drop(train_df.index)
# sorted according to count_study
test_df= test_df.sort_values(by=['count_instances'], ascending = False)
#Sample
train_df = train_df.sample(frac=0.89, weights='count_study', random_state=0) # train spliting size 80%
train_df= train_df.sort_values(by=['count_instances'], ascending = False)
val_df = df_Datacopy.drop(train_df.index.append(test_df.index))