【问题标题】:How can I replace a column given a specific condition in python?python - 如何在给定特定条件的python中替换列?
【发布时间】:2016-01-08 12:27:25
【问题描述】:

我有一个包含多个列的数据框,如下所示...

Chr1    Cufflinks   exon    28354206    28354551    .   .   .   gene_id "XLOC_008369"; transcript_id "TCONS_00014347"; exon_number "1"; oId "CUFF.2405.1"; class_code "u"; tss_id "TSS10073";
Chr1    Cufflinks   exon    28785549    28786194    .   .   .   gene_id "XLOC_008370"; transcript_id "TCONS_00014348"; exon_number "1"; oId "CUFF.2441.1"; class_code "u"; tss_id "TSS10074";
Chr1    Cufflinks   exon    29328712    29329210    .   .   .   gene_id "XLOC_008371"; transcript_id "TCONS_00014349"; exon_number "1"; oId "CUFF.2495.1"; class_code "u"; tss_id "TSS10075";
Chr1    Cufflinks   exon    29427951    29428406    .   .   .   gene_id "XLOC_008372"; transcript_id "TCONS_00014350"; exon_number "1"; oId "CUFF.2506.1"; class_code "u"; tss_id "TSS10076";
Chr1    Cufflinks   exon    29460116    29460585    .   .   .   gene_id "XLOC_008373"; transcript_id "TCONS_00014351"; exon_number "1"; oId "CUFF.2509.1"; class_code "u"; tss_id "TSS10077";

我想要做的是,如果我列表中的任何项目出现在数据框的一列中,那么我将第二列从 Cufflinks 替换为 lincRNA

一个问题是我用来制作字典中的键的列在数据框中有多行,因此我只得到唯一键,因此输出的总行数与输入。

到目前为止,这是我的代码...

#!/usr/bin/env python

file_in = open("lincRNA_final_transcripts.fa")
file_in2 = open("AthalianaslutteandluiN30merged.gtf")
file_out = open("updated.gtf", 'w')

sites = []
result = {}

for line in file_in:
    line = line.strip()
    if line.startswith(">"):
        line = line[1:]
        gene = str.split(line, ".")
        gene = gene[0]
        sites.append(gene)


for line2 in file_in2:
    line2 = line2.strip().split()
    line3 = str.split(line2[11], ";")
    line3 = line3[0]
    line3 = line3[1:-1]
    result[line3] = line2


for id in sites:
    id2 = str(id)
    if id2 in result.keys():
        result[id][1] = "lincRNA"

for val in result.values():
    file_out.write("\t".join(val))
    file_out.write("\n")

【问题讨论】:

  • 你能解释一下什么是df吗?
  • 除非首字母缩略词被广泛使用(即至少应该在维基百科的消歧页面en.wikipedia.org/wiki/DF 上列出),否则对于那些可能能够回答您的问题的人来说,它基本上毫无意义。
  • 对不起,它是一个数据框或多列文本文件
  • 我现在已经编辑了我的问题
  • 你为什么要重新发明轮子?在 Python 中有非常完善的数据/数据帧操作库,例如 pandas

标签: python dataframe


【解决方案1】:

我将尝试在pandas 中介绍如何执行此操作。 Pandas 是一个用于处理数据帧的 python 库,学习它可以很容易地进行数据帧操作。

  1. 安装熊猫

    sudo pip install pandas
    
  2. 将您的数据加载到 pandas 数据框对象中。 gtf 似乎是一个制表符分隔的文件,所以传递\t 作为分隔符。如果没有标题行传递None,如果第一行是标题则传递0。有关参数的更多信息,请参阅here

    import pandas
    df = pd.read_csv('AthalianaslutteandluiN30merged.gtf', sep = '\t', header = None, engine = 'python')
    
        0      1             2       3       4     5 6 7            8  
    0   Chr1    Cufflinks   exon 28354206 28354551 . . .    gene_id "XLOC_008369"   transcript_id "TCONS_00014347"  exon_number "1" oId "CUFF.2405.1"   class_code "u"  tss_id "TSS10073"
    1   Chr1    Cufflinks   exon 28785549 28786194 . . .    gene_id "XLOC_008370"   transcript_id "TCONS_00014348"  exon_number "1" oId "CUFF.2441.1"   class_code "u"  tss_id "TSS10074"
    
  3. 检查第 8 列中的字符串是否包含一个子字符串,该子字符串也包含在您的 sites 列表中。我们将使用this idea.

    sites = ["XLOC_008369", "XLOC_008369"]
    pattern = '|'.join(sites)
    mask = df[8].str.contains(pattern)
    
  4. 如果第 8 列包含与 sites 列表中的元素匹配的子字符串,则使用布尔索引将 Cufflinks 更改为 lincRNA。有关 pandas 索引的更多信息,请参阅 here

    df.loc[mask,1] = 'lincRNA'
    

编辑:使用str.contains 检查熊猫列是否包含列表中的元素。

【讨论】:

  • 这太棒了。当我阅读 gtf 文件时,我收到此错误“ValueError:第 48 行中的预期 18 个字段,看到 19”。你觉得我做错了什么?
  • @upendra Pandas 期望每一行都有相同的列数,在这种情况下它期望 18 列。但是,在第 48 行中,似乎有 19 列。最好打开您的文件,看看是否有多余的制表符或分号。
  • 你是对的,有几行有额外的列。有没有办法处理这些额外的列?
  • @upendra 我已经使用另一个函数编辑了我的回复来进行匹配。您不再需要使用分号作为分隔符,这会阻止出现其他列。
  • 它终于奏效了。非常感谢所有的帮助。非常感谢
猜你喜欢
  • 2012-01-21
  • 2021-05-18
  • 1970-01-01
  • 2013-08-30
  • 1970-01-01
  • 2015-12-29
  • 2018-12-20
  • 1970-01-01
  • 2021-10-10
相关资源
最近更新 更多