【问题标题】:Python dictionaries not copied properly causing repetitions, how to get this right?Python 字典没有正确复制导致重复,如何解决这个问题?
【发布时间】:2020-10-06 12:31:01
【问题描述】:

我正在编写一个函数,它应该比较列表(测试的重要基因)并列出所有可能的列表选择组合的共同元素(基因)。

这些结果将用于维恩图……

测试和基因的数量是灵活的。

输入的 JSON 文件如下所示:

| test              | genes                                                 |
|-----------------  |---------------------------------------------------    |
| p-7trt_1/0con_1   | [ENSMUSG00000000031, ENSMUSG00000000049, ENSMU...     |
| p-7trt_2/0con_1   | [ENSMUSG00000000031, ENSMUSG00000000037, ENSMU...     |
| p-7trt_1/0con_2   | [ENSMUSG00000000037, ENSMUSG00000000049, ENSMU...     |
| p-7trt_2/0con_2   | [ENSMUSG00000000028, ENSMUSG00000000031, ENSMU...     |
| p-7trt_1/0con_3   | [ENSMUSG00000000088, ENSMUSG00000000094, ENSMU...     |
| p-7trt_2/0con_3   | [ENSMUSG00000000028, ENSMUSG00000000031, ENSMU...     |

所以函数如下:

import pandas as pd
def get_venn_compiled_data(dir_loc):
    """return json of compiled data for the venn thing
    """
    data_frame = pd.read_json(dir_loc + "/venn.json", orient="records")
    number_of_tests = data_frame.shape[0]
    venn_data = []
    venn_data_point = {"tests": [], "genes": []} # list of genes which are common across listed tests
    binary = lambda x: bin(x)[2:] # to directly get the binary number
    for dec_number in range(1, 2 ** number_of_tests):

        # resetting
        venn_data_point["tests"] = []
        venn_data_point["genes"] = []

        # using a binary number to get all the cases
        for index, state in enumerate(binary(dec_number)):
            if state == "0":
                continue

            # putting in all the genes from the first test
            if venn_data_point["tests"] == []:
                venn_data_point["genes"] = data_frame["data"][index].copy()

            # removing the ones which are not common in current genes state and this.tests
            else:
                for gene_index, gene in enumerate(venn_data_point["genes"]):
                    if gene not in data_frame["data"][index]:
                        venn_data_point["genes"].pop(gene_index)

            # putting the test in the tests list
            venn_data_point["tests"].append(data_frame["name"][index])

        venn_data.append(venn_data_point.copy())
    return venn_data

我基本上是在滥用二进制数生成所有可能的 1 和 0 组合的事实,因此将二进制数的每个位置与测试相对应,对于每个二进制数,如果存在 0,则对应于该测试的列表不用于列表比较。

我已经尽力解释了,如果我不清楚,请在cmets中提问。

运行该函数后,我得到一个输出,其中有随机重复测试集的位置。

This is the test input file.

This is what cameout as the output

任何帮助都非常感谢谢谢。

【问题讨论】:

  • 没关系,发现我的错误会在某个时候把解决方案放在这里

标签: python json pandas dictionary list-comparison


【解决方案1】:

我意识到我犯了什么错误

我假设二进制函数总是会神奇地生成具有我需要的位置数量的字符串,但事实并非如此。

在更新二进制函数以添加这些零之后,一切正常。

import pandas as pd
def get_venn_compiled_data(dir_loc):
    """return json of compiled data for the venn thing
    """
    # internal variables
    data_frame = pd.read_json(dir_loc + "/venn.json", orient="records")
    number_of_tests = data_frame.shape[0]
    venn_data = []

    # defining internal function
    def binary(dec_no, length=number_of_tests):
        """Just to convert decimal number to binary of specified length
        """
        bin_number = bin(dec_no)[2:]

        if len(bin_number) < length:
            bin_number = "0" * (length - len(bin_number)) + bin_number

        return bin_number

    # list of genes which are common across listed tests
    venn_data_point = {
        "tests": [],
        "genes": [],
    }


    for dec_number in range(1, 2 ** number_of_tests):

        # resetting
        venn_data_point["tests"] = []
        venn_data_point["genes"] = []

        # using a binary number to get all the cases
        for index, state in enumerate(binary(dec_number)):
            if state == "0":
                continue

            # putting in all the genes from the first test
            if venn_data_point["tests"] == []:
                venn_data_point["genes"] = data_frame["data"][index].copy()

            # removing the ones which are not common in current genes state and this.tests
            else:
                for gene_index, gene in enumerate(venn_data_point["genes"]):
                    if gene not in data_frame["data"][index]:
                        venn_data_point["genes"].pop(gene_index)

            # putting the test in the tests list
            venn_data_point["tests"].append(data_frame["name"][index])

        venn_data.append(venn_data_point.copy())
    return venn_data

如果其他人对此有更优化的算法,不胜感激。

【讨论】:

    猜你喜欢
    • 2021-07-06
    • 1970-01-01
    • 2019-06-12
    • 2020-06-12
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    • 2021-08-22
    相关资源
    最近更新 更多