Использование функции apply в Pandas при обращении и циклическом просмотре другого df? - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть ссылка на препарат под названием df_drug_ref (ниже).Есть три препарата (A, B и C).Соответствующий УВД указан во втором столбце.Однако, если у пациента есть DIN в списке Drug_BIN_Id_Exclusion, то он / она не будет считаться использующим это лекарство (т. Е. 011235 для препарата A).называется df_row.Это охватывает все лекарства, отпускаемые каждым человеком.И у каждого человека есть свои 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                  

. Я хотел бы присвоить «1» для соответствующего препарата (повторяющийся цикл для проверки A, B или C и присвоение соответствующим столбцам)если в этом ряду код ATC совпадает со ссылкой на препарат, а 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

Я понимаю, как использовать функцию apply внутри того же самого df, но я не знаю, как также использовать внешний df в качестве ссылки.

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Это рабочее решение с использованием функции и значений:

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)
0 голосов
/ 27 ноября 2018

Сначала вы можете разбить свои списки на несколько столбцов с помощью 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_DIN» находится в одном из столбцов «Drug_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())

возможно быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...