代码之家  ›  专栏  ›  技术社区  ›  Denver Dang

多个大型阵列的内存问题

  •  1
  • Denver Dang  · 技术社区  · 6 年前

    (100, 100, 1000) 阵列。但正如我所想象的,在我的内存耗尽之前,它不会占用超过150-200个数组,而且它都会失败(至少在我当前的代码中是这样)。

    import numpy as np
    
    toxicity_data_path = open("data/toxicity.txt", "r")
    toxicity_data = np.array(toxicity_data_path.read().split("\n"), dtype=int)
    
    patients = range(1, 1000, 1)
    

    以上仅仅是每个阵列的1和0(表示毒性或不)的列表(在这种情况下,一个数组是一个病人的数据)。在这个病例中大约有1000个病人。

    然后,我从上面的代码创建两个列表,所以我有一个列表与病人的毒性,其中一个他们没有。

    patients_no_tox = [i for i, e in enumerate(toxicity_data.astype(np.str)) if e in set("0")]
    patients_with_tox = [i for i, e in enumerate(toxicity_data.astype(np.str)) if e in set("1")]
    

    然后我编写这个函数,它接受一个已经保存到磁盘阵列的( (100,100,1000)

    def log_likely_list(patient, remove_index_list):
        array_data = np.load("data/{}/array.npy".format(patient)).ravel()
        return np.delete(array_data, remove_index_list)
    
    
    remove_index_list = np.load("data/remove_index_list.npy")
    final_list = [log_likely_list(patient, remove_index_list) for patient in patients]
    

    下一步是创建两个列表,我需要我的计算。我和所有患者一起进行最后一个列表,并移除有毒性或不毒性的患者。

    patients_no_tox_list = np.column_stack(np.delete(final_list, patients_with_tox, 0))
    patients_with_tox_list = np.column_stack(np.delete(final_list, patients_no_tox, 0))
    

    log_likely = np.sum(np.log(patients_with_tox_list), axis=1) +
                 np.sum(np.log(1 - patients_no_tox_list), axis=1)
    

    我的问题,如前所述,当我得到大约150-200(在 patients 很明显,我试图保存磁盘上要加载的内容(这就是我加载这么多文件的原因),但这对我没有多大帮助。我想也许我可以一次去一个阵列 log_likely 函数,但最后,在求和之前,我可能只有一个同样大的数组,另外,如果我不能使用numpy sum等特性,计算速度可能会慢得多。

    1 回复  |  直到 6 年前
        1
  •  1
  •   mooglinux    6 年前

    每次使用列表理解时,都会在内存中创建数据的新副本。所以这句话:

    final_list = [log_likely_list(patient, remove_index_list) for patient in patients]
    

    包含所有1000名患者的完整数据!

    for...in...: 用括号代替括号的表达式。这可能看起来像:

    with_tox_data = (log_likely_list(patient, remove_index_list) for patient in patients_with_tox)
    with_tox_log = (np.log(data, axis=1) for data in with_tox_data)
    
    no_tox_data = (log_likely_list(patient, remove_index_list) for patient in patients_no_tox)
    no_tox_log = (np.log(1 - data, axis=1) for data in no_tox_data)
    
    final_data = itertools.chain(with_tox_log, no_tox_log)
    

    注意,实际上还没有执行任何计算:生成器在您迭代它们之前不会执行任何操作。在这种情况下汇总所有结果的最快方法 is to use reduce :

    log_likely = functools.reduce(np.add, final_data)