首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有效地查找其他行的31天内的行

有效地查找其他行的31天内的行
EN

Stack Overflow用户
提问于 2019-04-21 23:24:36
回答 1查看 70关注 0票数 1

我有一个非常大的数据帧(>5 5GB),其中的行包含以下信息:

PatientID StudyDate Modality SliceNo Filename

每一行由3D医学图像中的一个切片组成,对于模态,我有PETCT,这是两种不同类型的医学扫描。例如,我可以:

代码语言:javascript
复制
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扫描。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-23 06:05:37

以下算法不能涵盖所有情况,但我希望它也能有所帮助。

一开始,我们忽略了一些列,因为我们实际上只对cols = ['PatientID', 'StudyDate', 'Modality']感兴趣。所以我们写下

代码语言:javascript
复制
df = df[cols].sort_values(cols).drop_duplicates()

现在我们确定CTPT周期:

代码语言:javascript
复制
df['Modality_'] = df.groupby(['PatientID'])['Modality'].shift(1).fillna(method='bfill')
df['Group'] = (1-df['Modality_'].eq(df['Modality'])).cumsum()

接下来,我们计算每个周期的最大日期和最小日期

代码语言:javascript
复制
agg = df.pivot_table(index=['PatientID', 'Group'], columns=['Modality'], values=['StudyDate'], aggfunc=['max', 'min'])

最后,我们提取PTCT数据。因为CT周期总是跟在PT周期之后,所以我们可以按组将前一个周期移位一,然后直接比较它们

代码语言:javascript
复制
pt = agg.loc[:, ('max', 'StudyDate', 'PT')].groupby(['PatientID']).shift(1)
ct = agg.loc[:, ('min', 'StudyDate', 'CT')]

我们希望选择偏移量小于30天的日期:

代码语言:javascript
复制
ok = ct - pt < pd.offsets.Day(30)
ok = ok[ok == True].to_frame()

现在我们完成了:

代码语言:javascript
复制
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-21
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55784054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档