如何以高效的方式基于pandas中的其他行更新一行

rt4zxlrg  于 2023-04-28  发布在  其他
关注(0)|答案(2)|浏览(151)

我想根据其他行更新pandas df行上的值。
我有一个病人的数据框,他们需要接种的所有疫苗,一个列表明他们是否已经接种了疫苗,还有一个“状态”列,如果他们接种了疫苗,就是“OK”,如果他们没有接种,就是“Missing”。
问题是,有一些疫苗是等效的。在下面的实施例中,疫苗B和C是等同的。所以如果病人接种了B疫苗,就不应该接种C疫苗。因此,在这种情况下,疫苗B的正确状态为“OK”,疫苗C的正确状态为“应用的等效疫苗”。
dataframe超过200万行,所以我需要一种有效的方法来构建“desired_status”列。
有什么办法吗?谢谢!
| 病人|疫苗|应用?|地位|期望状态|
| --------------|--------------|--------------|--------------|--------------|
| 1|一个|1|好的|好的|
| 1|B|1|好的|好的|
| 1|C|0|失踪|应用的等效疫苗|
| 二|一个|0|失踪|失踪|
| 二|B|0|失踪|应用的等效疫苗|
| 二|C|1|好的|好的|
| 三|一个|1|好的|好的|
| 三|B|0|失踪|失踪|
| 三|C|0|失踪|失踪|
PS:等效疫苗不一定在相邻的排中。

c3frrgcw

c3frrgcw1#

您可以使用字典来Map等价项,然后使用groupby + aggnumpy.select

eq_vaccines = {'B': 'BC', 'C': 'BC'}

vac = df['vaccine'].map(eq_vaccines).combine_first(df['vaccine'])
applied_any = df.groupby(['patient', vac])['applied?'].transform('max').eq(1)

import numpy as np
df['status'] = np.select([df['applied?'].eq(1), applied_any],
                         ['Ok', 'Applied equivalent vaccine'], 'Missing')

输出:

patient vaccine  applied?                      status
0        1       A         1                          Ok
1        1       B         1                          Ok
2        1       C         0  Applied equivalent vaccine
3        2       A         0                     Missing
4        2       B         0  Applied equivalent vaccine
5        2       C         1                          Ok
6        3       A         1                          Ok
7        3       B         0                     Missing
8        3       C         0                     Missing
中间体表,以便于说明
patient vaccine  applied?                      status  vac  applied_any
0        1       A         1                          Ok    A            1
1        1       B         1                          Ok   BC            1
2        1       C         0  Applied equivalent vaccine   BC            1
3        2       A         0                     Missing    A            0
4        2       B         0  Applied equivalent vaccine   BC            1
5        2       C         1                          Ok   BC            1
6        3       A         1                          Ok    A            1
7        3       B         0                     Missing   BC            0
8        3       C         0                     Missing   BC            0
cx6n0qe3

cx6n0qe32#

def function1(dd:pd.DataFrame):
    dd1=dd.iloc[1:,[3]]
    if dd1.squeeze().eq("Ok").any():
        dd.loc[dd1.query("status == 'Missing'").index,'status']='Applied-equivalent-vaccine'
    return dd['status']

df1.groupby('patient',group_keys=False).apply(function1)

输出:

0                            Ok
1                            Ok
2    Applied-equivalent-vaccine
3                       Missing
4    Applied-equivalent-vaccine
5                            Ok
6                            Ok
7                       Missing
8                       Missing

相关问题