如何使python循环更快地运行成对关联测试

2024-09-30 08:17:45 发布

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

我有一份病人身份证和药物名的清单,还有一份病人证号和疾病名的清单。我想为每种疾病找到最有指导意义的药物。在

为了找到这一点,我想做一个Fisher精确测试,以得到每个疾病/药物对的p值。循环运行了10个多小时。有没有一种方法可以使循环更有效,或者更好地解决这个关联问题?在

我的循环:

import numpy as np
import pandas as pd
from scipy.stats import fisher_exact 

most_indicative_medication = {}
rx_list = list(meps_meds.rxName.unique()) 
disease_list = list(meps_base_data.columns.values)[8:]

for i in disease_list:
    print i
    rx_dict = {}
    for j in rx_list: 
        subset = base[['id', i, 'rxName']].drop_duplicates()
        subset[j] = subset['rxName'] == j
        subset = subset.loc[subset[i].isin(['Yes', 'No'])]
        subset = subset[[i, j]]
        tab = pd.crosstab(subset[i], subset[j]) 
        if len(tab.columns) == 2:
            rx_dict[j] = fisher_exact(tab)[1]
        else: 
            rx_dict[j] = np.nan
    most_indicative_medication[i] = min(rx_dict, key=rx_dict.get)

Tags: importasnprxtabdictlistexact
2条回答

更快的运算速度是好的,但是更好的算法通常会胜过它;-)

补充一点

import numpy as np
import pandas as pd
from scipy.stats import fisher_exact

# data files can be download at
# https://github.com/Saynah/platform/tree/d7e9f150ef2ff436387585960ca312a301847a46/data
meps_meds      = pd.read_csv("meps_meds.csv")               #  8 cols * 1,148,347 rows
meps_base_data = pd.read_csv("meps_base_data.csv")          # 18 columns * 61,489 rows

# merge to get disease and drug info in same table
merged = pd.merge(                                          # 25 cols * 1,148,347 rows
    meps_base_data, meps_meds,
    how='inner', left_on='id', right_on='id'
)

rx_list        = meps_meds.rxName.unique().tolist()         # 9218 items
disease_list   = meps_base_data.columns.values[8:].tolist() # 10 items

请注意,rx_list有很多重复项(例如,如果包含拼写错误,则为阿莫西林输入52个条目)。在

那么

^{pr2}$

现在在我的机器上运行大约18分钟,您可以将其与EM28的答案结合起来,将其速度提高4倍或更多。在

你需要多处理/多线程,我已经添加了代码

from multiprocessing.dummy import Pool as ThreadPool
most_indicative_medication = {}
rx_list = list(meps_meds.rxName.unique()) 
disease_list = list(meps_base_data.columns.values)[8:]

def run_pairwise(i):
    print i
    rx_dict = {}
    for j in rx_list: 
        subset = base[['id', i, 'rxName']].drop_duplicates()
        subset[j] = subset['rxName'] == j
        subset = subset.loc[subset[i].isin(['Yes', 'No'])]
        subset = subset[[i, j]]
        tab = pd.crosstab(subset[i], subset[j]) 
        if len(tab.columns) == 2:
            rx_dict[j] = fisher_exact(tab)[1]
        else: 
            rx_dict[j] = np.nan
    most_indicative_medication[i] = min(rx_dict, key=rx_dict.get)

pool = ThreadPool(3)
pairwise_test_results = pool.map(run_pairwise,disease_list)
pool.close()
pool.join()

注:http://chriskiehl.com/article/parallelism-in-one-line/

相关问题 更多 >

    热门问题