如何创建按日期排序的groupby ID变量第一次出现的指示符列?

2024-05-19 08:11:42 发布

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

我有一些医院就诊医疗保健数据,其格式为:

^{tb1}$

我想创建一列COUNSELLING_STARTED,它指示客户机CLIENT_ID是否已经开始咨询,但只是第一次。i、 e.第一次发生时COUNSELLING_COUNT == 1对于每个CLIENT_ID,应产生以下数据帧:

^{tb2}$

下面是生成数据帧的代码:

data = {'CLIENT_ID':[54950,54950,54950,54950,54950,67777,67777,67777,70000,70000],
'DATE_ENCOUNTER':['2017-11-24','2018-01-19','2018-03-13','2018-05-11','2018-12-17','2015-09-01','2015-12-01','2016-02-28','2019-06-07','2019-08-09'],
'DATE_COUNSELLING':[np.nan,np.nan,np.nan,'2018-04-30','2018-06-25',np.nan,np.nan,'2016-02-28','2019-06-07','2019-06-07'],
'COUNSELLING_COUNT':[0,0,0,1,3,0,0,1,1,1]}

df = pd.DataFrame(data)

Tags: 数据clientiddatadate客户机格式count
1条回答
网友
1楼 · 发布于 2024-05-19 08:11:42

更新

在我最初的回答中,我忽略了一个事实,即如果某人没有咨询日期,我的方法会为他们的第一个条目指定一个1。这里有两种快速解决方法

一个选项是在执行我所描述的groupby之前,显式删除带有NA的行:

dropped = df[~df['DATE_COUNSELLING'].isna()]
df.loc[:, 'COUNSELLING_STARTED'] = 0
df.loc[dropped['DATE_COUNSELLING'].isna().groupby(dropped['CLIENT_ID']).idxmin(), 'COUNSELLING_STARTED'] = 1
# note that `dropped` is used inside the brackets in the last line

第二种选择是完全按照我之前所做的做,然后覆盖错误条目(即,咨询是NA的地方):

df.loc[:, 'COUNSELLING_STARTED'] = 0
df.loc[df['DATE_COUNSELLING'].isna().groupby(df['CLIENT_ID']).idxmin(), 'COUNSELLING_STARTED'] = 1
df.loc[df['DATE_COUNSELLING'].isna(), 'COUNSELLING_STARTED'] = 0
# last line catches people with no counseling

这是我最初的回答:

df.loc[:, 'COUNSELLING_STARTED'] = 0
df.loc[df['DATE_COUNSELLING'].isna().groupby(df['CLIENT_ID']).idxmin(), 'COUNSELLING_STARTED'] = 1

解释(使用我的第一种方法):

找出咨询日期在哪里nan;然后按客户端ID分组并找到最小值的索引(这将是第一个条目):

>>> dropped['DATE_COUNSELLING'].isna().groupby(dropped['CLIENT_ID']).idxmin()
CLIENT_ID
54950    3
67777    7
70000    8
Name: DATE_COUNSELLING, dtype: int64

您正在使用这些索引来选择在新列中写入1的位置。即使dropped没有任何NA值,我们仍然在groupby中使用.isna()来获得一个值,我们可以使用min(而不是字符串)。您还可以执行类似.astype(bool)的操作

最后的df是:

   CLIENT_ID DATE_ENCOUNTER  ... COUNSELLING_COUNT  COUNSELLING_STARTED
0      54950     2017-11-24  ...                 0                    0
1      54950     2018-01-19  ...                 0                    0
2      54950     2018-03-13  ...                 0                    0
3      54950     2018-05-11  ...                 1                    1
4      54950     2018-12-17  ...                 3                    0
5      67777     2015-09-01  ...                 0                    0
6      67777     2015-12-01  ...                 0                    0
7      67777     2016-02-28  ...                 1                    1
8      70000     2019-06-07  ...                 1                    1
9      70000     2019-08-09  ...                 1                    0

[10 rows x 5 columns]

如果您希望显式选择最早的咨询日期(而不是第一个非NA值),则可以将其用作索引器:

>>> pd.to_datetime(dropped['DATE_COUNSELLING']).groupby(dropped['CLIENT_ID']).idxmin()
CLIENT_ID
54950    3
67777    7
70000    8
Name: DATE_COUNSELLING, dtype: int64

这在这里给出了相同的结果,因为对每个客户的日期进行了排序(即,最早观察到的日期是第一个非NA值)

相关问题 更多 >

    热门问题