Skip to main content
 首页 » 编程设计

Python:将文件中的行转换为列

2025年05月04日18qq号

我是一名 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 列,区域得分(第 1-2 列)之后的 20 列是 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] 添加到列表中。

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

在此先感谢您,非常感谢您的帮助!

请您参考如下方法:

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

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

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

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

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

lol = [] 

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

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