我有一个非常大的数据帧(>5 5GB),其中的行包含以下信息:
PatientID StudyDate Modality SliceNo Filename
每一行由3D医学图像中的一个切片组成,对于模态,我有PET和CT,这是两种不同类型的医学扫描。例如,我可以:
PatientID StudyDate Modality SliceNo Filename
000000001 2017-08-01 PT 0 XXXXX
000000001 2017-08-01 PT 1 XXXXX
...
000000001 2017-08-01 PT 100 XXXXX
000000001 2017-04-01 PT 0 XXXXX
000000001 2017-04-01 PT 1 XXXXX
...
000000001 2016-08-01 CT 0 XXXXX
000000001 2016-08-01 CT 1 XXXXX
...
000000001 2016-08-01 CT 100 XXXXX
000000001 2017-04-15 CT 0 XXXXX
000000001 2017-04-15 CT 1 XXXXX
...
000000001 2017-04-15 CT 100 XXXXX
...
000000002 2016-07-01 PT 0 XXXXX
000000002 2016-07-01 PT 1 XXXXX
...
000000002 2016-07-01 PT 100 XXXXX
000000002 2015-07-21 PT 0 XXXXX
000000002 2015-07-21 PT 1 XXXXX
...
000000002 2015-07-21 PT 100 XXXXX
000000002 2014-07-01 PT 0 XXXXX
000000002 2014-07-01 PT 1 XXXXX
...
000000002 2014-07-01 PT 100 XXXXX
000000002 2015-08-05 CT 0 XXXXX
000000002 2015-08-05 CT 1 XXXXX
...
000000002 2015-08-05 CT 100 XXXXX现在我想找出与CT扫描相对应的每个患者的PT,其中,如果在CT扫描之前不到一个月进行了对应,则定义对应关系。可以取消(丢弃)其他扫描。一般来说,可能会有多个CT扫描和多个PT扫描,但每个CT都应该有一个与之相关的扫描。例如,如果CT扫描的日期是2017-04-01,则2017-03-01和2017-04-01之间的所有PT扫描都符合条件。
什么是选择那些满足条件的PT扫描的有效方法:对于该患者,最多一个月后进行CT扫描?
例如,患者000000001 2016-08-01的CT将没有关联的PT扫描(这很好),但将选择2017-04-01的PT扫描,因为2017-04-15的CT扫描是在PT扫描后最多31天进行的。因此,在这种情况下,2017-08-01的PT扫描被过滤掉。应过滤符合此条件的所有切片(SliceNo) (每次扫描可以有不同数量的切片)。对于患者000000002,仅保留2015-07-21年的PT扫描。
发布于 2019-04-23 06:05:37
以下算法不能涵盖所有情况,但我希望它也能有所帮助。
一开始,我们忽略了一些列,因为我们实际上只对cols = ['PatientID', 'StudyDate', 'Modality']感兴趣。所以我们写下
df = df[cols].sort_values(cols).drop_duplicates()现在我们确定CT和PT周期:
df['Modality_'] = df.groupby(['PatientID'])['Modality'].shift(1).fillna(method='bfill')
df['Group'] = (1-df['Modality_'].eq(df['Modality'])).cumsum()接下来,我们计算每个周期的最大日期和最小日期
agg = df.pivot_table(index=['PatientID', 'Group'], columns=['Modality'], values=['StudyDate'], aggfunc=['max', 'min'])最后,我们提取PT和CT数据。因为CT周期总是跟在PT周期之后,所以我们可以按组将前一个周期移位一,然后直接比较它们
pt = agg.loc[:, ('max', 'StudyDate', 'PT')].groupby(['PatientID']).shift(1)
ct = agg.loc[:, ('min', 'StudyDate', 'CT')]我们希望选择偏移量小于30天的日期:
ok = ct - pt < pd.offsets.Day(30)
ok = ok[ok == True].to_frame()现在我们完成了:
print(ok.join(ct.to_frame()))
0 (max, StudyDate, CT)
PatientID Group
1 2 True 2017-04-15
2 4 True 2015-08-05
print(ok.join(pt.to_frame()))
0 (max, StudyDate, PT)
PatientID Group
1 2 True 2017-04-01
2 4 True 2015-07-21https://stackoverflow.com/questions/55784054
复制相似问题