在Pandas中使用apply函数,同时引用和循环另一个df



我有一个名为df_drug_ref的df的药物参考(如下(。有三种药物(A、B和C(。第二列中列出了相应的ATC。然而,如果患者的DIN在Drug_BIN_Id_Exclusion列表中,则他/她不会被视为使用该药物(即药物a的011235(。

Drug        Drug_ATC_Id         Drug_DIN_Id_Exclusion
A           N123                [011235]
B           B5234               [65413, 654351]
C           N32456              []

下面是另一个名为df_row的df。这会捕获每个人分配的所有药物。每个人都有自己的CCD_ 3。

People_Id   Drug_ATC            Drug_DIN                A           B           C
1001        N123                                        
1001        N123                011235                  
1001        N32456              011232                  
1001        N111                                        
1002        B5234               65413                       
1002        B5234               654090                  
1002        N123                011235                  

如果在该行中,ATC代码与药物参考匹配,并且DIN不包含在排除列表中,我想为相应的药物分配"1"(循环迭代检查A、B或C并分配给相应的列(。结果应该是:

People_Id   Drug_ATC            Drug_DIN                A           B           C
1001        N123                                        1           0           0
1001        N123                011235                  0           0           0
1001        N32456              011232                  0           0           1
1001        N111                                        0           0           0
1002        B5234               65413                   0           0           0       
1002        B5234               654090                  0           1           0
1002        N123                011235                  0           0           0

我知道如何在同一个df中使用apply函数,但我不知道如何也使用外部df作为引用。

首先,您可以将列表拆分为几个列,并将apply(pd.Series)join分别拆分为df_drug_ref:

print (df_drug_ref.join(df_drug_ref['Drug_DIN_Id_Exclusion'].apply(pd.Series)))
Drug Drug_ATC_Id Drug_DIN_Id_Exclusion       0       1
0    A        N123              [011235]  011235     NaN
1    B       B5234       [65413, 654351]   65413  654351
2    C      N32456                    []     NaN     NaN

然后,您可以在列"Drug_ATC"上merge,在对列进行一些清理后,将上述连接的数据帧连接到People_Id

df_merge = People_Id.merge(df_drug_ref[['Drug', 'Drug_ATC_Id']]
.join(df_drug_ref['Drug_DIN_Id_Exclusion']
.apply(pd.Series)
.add_prefix('Drug_DIN_'))
.rename(columns={'Drug_ATC_Id':'Drug_ATC'}),
how='left')

获取df_merge:

People_Id Drug_ATC Drug_DIN Drug Drug_DIN_0 Drug_DIN_1
0       1001     N123             A     011235        NaN
1       1001     N123   011235    A     011235        NaN
2       1001   N32456   011235    C        NaN        NaN
3       1001     N111           NaN        NaN        NaN
4       1002    B5234    65413    B      65413     654351
5       1002    B5234   654090    B      65413     654351
6       1002     N123   011235    A     011235        NaN

现在,您可以将"Drug"列替换为NaN,其中"Drug_DIN"中的值位于其中一个具有np.any:的"Drug_DIN_i"列中

mask = np.any(df_merge.filter(like='Drug_DIN').iloc[:,:1].values == 
df_merge.filter(like='Drug_DIN').iloc[:,1:].values, axis=1)
df_merge.loc[mask,'Drug'] = np.nan

最后,创建列A、B、C。。。可以将pd.get_dummiesset_index一起使用,然后使用reset_index:

new_People_Id = pd.get_dummies(df_merge.set_index(['People_Id','Drug_ATC','Drug_DIN'])['Drug']).reset_index()
print (new_People_Id)
People_Id Drug_ATC Drug_DIN  A  B  C
0       1001     N123           1  0  0
1       1001     N123   011235  0  0  0
2       1001   N32456   011235  0  0  1
3       1001     N111           0  0  0
4       1002    B5234    65413  0  0  0
5       1002    B5234   654090  0  1  0
6       1002     N123   011235  0  0  0

注意这里你也可以使用join,例如:

new_People_Id = df_merge[['People_Id','Drug_ATC','Drug_DIN']].join(df_merge['Drug'].str.get_dummies())

也许更快。

这是一个使用函数和iterrows:的工作解决方案

def check_rx_condition(row):
for index, col in df_drug_ref.iterrows():
if ((col['Drug_ATC_Id'] in row['Drug_ATC'])&
(row['DRUG_DIN'] not in col['Drug_DIN_Id_Exclusion'])):
row[col['Drug']] = 1
else:
row[col['Drug']] = 0
return row
df_row = df_row.apply(check_rx_condition, axis=1)

最新更新