1

我是一个 python 初学者,试图制作一个脚本,使用制表符分隔的文本文件作为输入将指定的行转换为列。以下是文件中的行示例:

1   chr1    1008376 1258657 250281  4628    666 2832    565 16.6323226376   83.3676773624
1   chr1    1258657 1516806 258149  2544    601 1481    231 13.4929906542   86.5070093458
1   chr1    1516806 1766886 250080  1652    590 936 63  6.30630630631   93.6936936937
1   chr1    1766886 2017159 250273  5030    1608    2698    362 11.8300653595   88.1699346405

本质上,该文件遍历个体(第 0 列)染色体(第 1 列)中的区域列表(第 2-3 列),并给出为该区域(第 9 列)计算的统计数据。该文件首先列出了个体 1 的所有区域,然后是 2,直到最后一个个体。档案中有20个人。我想要一个不包含第 0 列或第 4-8 列的新文件,并且具有新列,这些新列是每个人在该行(现在是第 1-2 列)中的区域得分。因此,对于个人 1,第 3 列现在将是以前的第 9 列,第 4 列将是个人 2 中该区域的得分,依此类推。因此,每一行都有第 2 列(chr1)作为第 0 列,区域得分之后的 20 列(第 1-2 列)是 20 个人中每个人的得分。目前分数是成行的,所以文件有很多行。第 1-3 列中的每个个体值都是相同的,因此不存在区域不重叠的问题。此外,所有个人都具有相同的行数。换句话说,第 2+3 列在文件中重复了 20 次。

如果这太复杂/密集,下面的解释是一个简化的例子来说明问题。

这是我想要的一个简单的虚拟示例:

原始文件:

1 chr1 10 20 30423
1 chr1 20 30 40556
2 chr1 10 20 73476
2 chr1 20 30 43657
3 chr1 10 20 34656.5
3 chr1 20 30 90848

变成:

chr1 10 20 30423 73476 34656.5
chr1 20 30 40556 43657 90848

因此,如果任何 python 用户有一些关于将行转换为列的技巧,即使你没有时间专门解决这个问题,我也会发现行到列转换是一个特别棘手的问题,尤其是当它以列中的值为条件(此处为第 0 列)。

如果我能澄清问题,请告诉我。任何帮助或意见表示赞赏。

所以更新:感谢您的所有评论,这是我到目前为止的想法:

ListofData = [] # make list
individual=1 # only interested in first individual to get list of windows for the chromosome
for line in file('/mnt/genotyping/Alex/wholegenome/LROH/LROHSplitbyChrom/Filtered_by_MappingQuality20/SimpleHomozygosityScore/HomozygosityStatisticsTameratsalllanesMinMQ20chr20'): 
    line = line.rstrip() 
    fields = line.split("\t")
    if "chr" in line: #avoids header 
        if int(fields[0]) == individual:
            ListofData.extend(fields[2:5]) # add start, end and size of window to list

        else: # once iterated through windows, split the list into sets of three, making it one list per line
            lol = [ListofData[i:i+3] for i in range(0, len(ListofData), 3)] #list of lists divided into 3's

smallcounter = 0
for i in lol: #for set of 3 in list
    for line in file('/mnt/genotyping/Alex/wholegenome/LROH/LROHSplitbyChrom/Filtered_by_MappingQuality20/SimpleHomozygosityScore/HomozygosityStatisticsTameratsalllanesMinMQ20chr20'):
        if "chr" in line: # avoids header 
            line = line.rstrip() 
            fields = line.split("\t")
            if str(fields[2]) == lol.pop(0): #if start position in line matches start position in i
                i.extend(fields[9]) #add homozygosity score to list
                counter = counter + 1
            if smallcounter == 20: #if gone through all individuals in file
                smallcounter = 0 #reset counter for next try
                print i

我浏览了文件以在第 2-4 列中获取我想要的信息并将其放入列表中。然后我把这个列表分成每行对应的 3 组。然后在第二个循环中,我试图说对于列表中的每组 3 个(因此对于列表中的每个列表)遍历文件,并且如果列表中的第一个位置与文件中的起始位置相同( fields[2]) 然后将 fields[9] 中的分数添加到该列表中。然后我需要做的就是一个接一个地打印列表以获得我想要的。但是我对这条线有困难:

if str(fields[2]) == lol.pop(0):

我希望 python 查看列表中的第一个位置,最初是 fields[2] 并询问它是否与它循环通过的行中的 fields[2] 位置相同。如果是,那么它应该将字段 [9] 附加到列表中。

如果我需要更好地解释,请告诉我。

非常感谢您,非常感谢您的帮助!

4

3 回答 3

4

开始使用一门新语言是很困难的,你必须从某个地方开始。幸运的是,您选择了 Python,并且拥有 Python 命令行。使用它,您可以测试如何创建列,等等。

首先,您需要读入输入文件,并处理每一行中的信息。Python CSV 模块非常棒。我在水务项目中到处使用它,随后在许多其他需要 .csv 处理的项目中使用它。

但是你有一个制表符分隔的文件。我从未尝试将分隔符设置为制表符并验证它与制表符分隔的文件一起使用。如果尝试这样做不起作用 - 您可以在 Python 命令行中对其进行测试 - 作为一种解决方法,您可以将制表符分隔的文件通过管道传输到 sed 并将制表符转换为逗号。

至于列、行表示,在 Python 中,您必须有一个列表列表。那就是你需要有 [[1,2][3,4]...]。

Python 中的列表是可变的,因此您可以附加到它们。您会将列表列表初始化为空列表

lol = []

然后,您需要根据您想要跨越的列数向大声笑添加一个列表。假设您将仅包含数字的两列行放在一起,作为练习,您可以这样做:

lol.append([1,2])
lol.append([3,4])
lol.append([5,6])

>>> lol
[[1, 2], [3, 4], [5, 6]]
于 2012-06-10T14:07:34.570 回答
1

这里有一些代码可以让您了解可以做什么。我将省略花里胡哨的东西(例如,前三个if's可以在循环中更优雅地完成;等等),只提供基本代码。我正在读取文件“chr.txt”并写入stdout

def readTabbedFile(filename):
    out = {}
    file = open(filename, 'r')
    for line in file.readlines():
        line = line.rstrip('\n\r')
        parsedLine = line.split('\t')
        if not parsedLine[1] in out:
            out[parsedLine[1]] = {}
        if not parsedLine[2] in out[parsedLine[1]]:
            out[parsedLine[1]][parsedLine[2]] = {}
        if not parsedLine[3] in out[parsedLine[1]][parsedLine[2]]:
            out[parsedLine[1]][parsedLine[2]][parsedLine[3]] = []

        out[parsedLine[1]][parsedLine[2]][parsedLine[3]].append(parsedLine[9])

    for key0 in out.keys():
        for key1 in out[key0].keys():
            for key2 in out[key0][key1].keys():
                outStr = key0 + "\t" + key1 + "\t" + key2 + "\t"
            for val in out[key0][key1][key2]:
                outStr += "\t" + val
                print(outStr)

    file.close()

if __name__ == '__main__':
    readTabbedFile("chr.txt")
于 2012-06-10T14:49:06.750 回答
1

您可以将您的问题与列表理解相关联,以将行转换为矩阵中的列。

在此处输入图像描述

于 2015-05-09T12:23:38.003 回答