我有一个称为df_drug_ref
的药品参考资料(如下)。一共有三种药物(A,B和C)。相应的ATC列在第二栏中。但是,如果患者在Drug_BIN_Id_Exclusion
列表中具有DIN,则他/她将不被视为正在使用该药物(例如,药物A为011235)。
Drug Drug_ATC_Id Drug_DIN_Id_Exclusion
A N123 [011235]
B B5234 [65413, 654351]
C N32456 []
以下是另一个名为df_row的df。这捕获了每个人分配的所有药物。每个人都有自己的People_Id
。
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代码与药物参考和药物参考相匹配,我想为相应的药物分配“ 1”(迭代循环以检查A,B或C并分配给相应的列) DIN不包含在排除列表中。结果应该是:
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作为参考。
答案 0 :(得分:1)
首先,您可以使用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
然后,在对列进行了一些清理之后,可以将上面加入的数据框merge
上的{Drug_ATC}列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
现在,您可以用NaN替换“ Drug”列,其中“ Drug_DIN”中的值在{Dell_DIN_i”列之一中用np.any
:
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_dummies
与set_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())
也许更快。
答案 1 :(得分:1)
这是使用函数和迭代功能的可行解决方案:
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)