【问题标题】:How do I add information to specific cells in a Pandas DataFrame based on the variable name of the column as well as the row?如何根据列和行的变量名称向 Pandas DataFrame 中的特定单元格添加信息?
【发布时间】:2016-12-08 10:31:19
【问题描述】:

注意:我已经简化了这段代码和一些背景信息,以便查明确切的问题。如果您希望我解释此代码的其他方面,请在 cmets 中询问。

我目前正在尝试制作一个能够将两个或多个字典聚合在一起的代码,以最终制作一个包含以下基本设置的 .csv 文件:

                 TF-A       TF-A     TF-B       TF-B     
ids  gene name  score sum   hits    score sum   hits  ...  gene description  
id1   gene A    53.85         14       37.65      7   ...   stuff
id2   gene B    97.55         11       63.94      8   ...   stuff
id3   gene C    88.67         9        79.43      12  ...   stuff
id4   gene D    69.35         12       13.03      13  ...   stuff
...   ......    ......        ...       ...      ...  ..........
idx   gene Z    49.32         8        84.03      10  ...   stuff

字典包含作为键的基因名称,对应的值是一个分数数组(这些分数是通过计算转录因子(又名 TF)在某个位置与基因结合的概率生成的)。每个 TF 都有一个 dict,它的 key 只包含至少有一个分数的基因。打开字典后,使用集合交集来生成所有给定转录因子共有的基因列表,然后将其组织到 for 循环中“基因名称”列中的数据框中。由于之前构建的类结构(未显示),我可以轻松检索每个基因的通用名称和描述,并使用 df.set_value 将其放在“基因描述”列中。

for id in common_names:
    gene_name= idconverter.getgene(id).gene_name
    gene_description= idconverter.getgene(id).description
    df.set_value(id,'gene name', gene_name)
    df.set_value(id,'gene name', gene_description)

但是,数据框中的列数取决于用户希望分析的转录因子的数量。因此,用户放入两个 TF 将向数据帧添加四列——两列用于 TF-A(分数和分数的总和,或“命中”),两列用于 TF-B。输入三个 TF 将产生六列,输入四个 TF 将产生八列,依此类推。 ID、基因名称和描述列是不变的。

所以,在我构建数据框之前,我会为每个给定的 TF 创建一个列表。

ColumnList = []
for tf_id in tf_id_list:    
    ColumnList+=['{} Total Sum of Hits'.format(tf_id), '{} Number of Hits'.format(tf_id)]

通过这个列表,我将它与其他列名连接起来,然后实例化我的数据框。

df= DataFrame(columns= ['ids','gene name']+ColumnList+['gene description']) 

如上所示,我可以轻松地在数据框中的正确单元格中设置名称和描述。而且我可以根据原始字典中的 TF 轻松计算每个基因的命中数和总得分总和,但我不知道如何将这些信息放在相应的单元格中。因为列数取决于输入的 TF,所以我不知道我应该编写什么样的代码来适应这个可变的列数,或者如何根据其附着的 TF 指定列。有人可以推荐我正确的代码设置和/或方法吗?

我做了一些研究,我确实看到了一种方法,可以根据另一列(但在同一行)中存在的信息类型将某条信息添加到单元格中:

Modifying a subset of rows in a pandas dataframe

df.ix[df.A==0, 'B'] = np.nan

如果您阅读了上面提供的链接中的代码,只要“A”列中出现零,上面的这段代码就会在“B”列中添加一个 NaN。我认为我可以利用这种方法,但考虑到我需要根据它们与第一个 TF、第二个 TF 还是第三个 TF 等相关来添加命中数和总得分。有人会写:

for id in common_genes:
    for tf_id in tf_id_list:
        df.ix[df.'{} Number of Hits'.format(tf_id)== tf_id]= number_hits
        df.ix[df.'{} Total Sum of Scores'.format(tf_id)== tf_id]= sum_scores    

我不认为这是正确的,因为我的 IDE 说语法无法编译。我还应该注意,我已经稍微简化了上面的代码——变量“number_hits”和“sum_scores”实际上是从包含基因名称作为键的字典中派生的,以及命中列表、分数总和和相关的 TF 名称作为值。

【问题讨论】:

    标签: python-2.7 pandas dictionary


    【解决方案1】:

    最后,我决定制作一个 dicts 的 dict——我意识到这种数据结构实际上是我所需要的最理想的。来自原始字典的信息将存储在字典(“total_dict”)中,当且仅当基因存在于 common_genes 列表中时才会访问这些信息(来自所有转录因子的集合)有共同点)。通过设置一个for循环来访问它们,以通过total_dict的TF来确定基因id是否存在于TF dict中,如果存在,则值中的信息(即分数总和和命中数)是添加到正确的行(基于基因名称或 id)和列(基于手头的 TF)。

    for id in common_names:
        gene_name= idconverter.getgene(id).gene_name
        gene_description= idconverter.getgene(id).description
        df.set_value(id,'gene name', gene_name)
        df.set_value(id,'gene name', gene_description)
        for tf_id in total_dict.keys():
            if id in total_dict[tf_id].keys():
                df.set_value(id, '{} Score Sum'.format(tf_id), total_dict[tf_dict][id][0])
                df.set_value(id, '{} Score Sum'.format(tf_id), total_dict[tf_dict][id][1])
    print(df.header())
    

    长话短说,如果您要处理大量不同类型的数据,请确保您使用的数据结构可以被操纵,以构建您想要生成的结果。

    【讨论】:

      猜你喜欢
      • 2021-12-24
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 2013-01-19
      • 2022-01-09
      • 1970-01-01
      • 2018-08-13
      • 1970-01-01
      相关资源
      最近更新 更多