从多个文件中提取特定列&写入文件Python

时间:2016-05-05 22:56:09

标签: python-2.7

我是Stackoverflow的新手,我正在学习Python。我真的希望你能帮助解决使用Python的以下问题。所以,我有七个制表符分隔文件,每个文件都有列的确切数量和名称,但每个文件的数据不同。下面是七个文件中的任何一个的示例:

 test_id gene_id gene    locus   sample_1        sample_2        status  value_1 value_2 log2(fold_change)
  000001     000001     ZZ 1:1   01  01   NOTEST  0       0       0       0       1       1       no

我试图基本上读取所有这七个文件并提取第三,第四和第十列(基因,locus,log2(fold_change))并将这些列写入新文件中。所以文件看起来像这样:

gene name   locus   log2(fold_change)    log2(fold_change)    log2(fold_change)    log2(fold_change)    log2(fold_change)    log2(fold_change)    log2(fold_change)
ZZ  1:1         0     0     0     0

所有log2(fold_change)都是从七个文件中的每一个的第十列获得的

到目前为止我所拥有的是需要帮助构建一个更有效的pythonic方式来完成上面的任务,注意代码仍然没有完成上面解释的任务,需要一些工作

 dicti = defaultdict(list)
 filetag = []

 def read_data(file, base):
  with open(file, 'r') as f:
    reader = csv.reader((f), delimiter='\t')
     for row in reader:
      if 'test_id' not in row[0]:
            dicti[row[2]].append((base, row))

 name_of_fold = raw_input("Folder name to stored output files in: ")
 for file in glob.glob("*.txt"):
  base=file[0:3]+"-log2(fold_change)"
  filetag.append(base)
  read_data(file, base)


 with open ("output.txt", "w") as out:
  out.write("gene name" + "\t"+  "locus" + "\t" + "\t".join(sorted(filetag))+"\n")
  for k,v in dicti:
   out.write(k + "\t" + v[1][1][3] + "\t" + "".join([ int(z[0][0:3]) * "\t" + z[1][9]  for z in v ])+"\n")

所以,上面的代码是一个有效的代码,但这不是我在寻找的原因。输出代码是问题,我在第一列(k)写了一个制表符分隔的输出文件,v [1] [1] [3]是那个特定基因的基因座,最后哪个是我的我的编码时间很难,这是输出文件的一部分:

 "".join([ int(z[0][0:3]) * "\t" + z[1][9]  for z in v ])

我试图从该特定基因和基因座的七个文件中的每个文件中提供折叠更改列表,然后将其写入正确的列号,因此我基本上将文件编号的列号乘以“ \ t“这将确保该值将转到正确的列,问题是当另一个文件的下一列变长时,写入将从它停止写入的地方开始,我不想要,我想从写作开始再次开始:

这就是我的意思,例如,

 gene name   locus     log2(fold change) from file 1    .... log2(fold change) from file7 
 ZZ           1:3      0           
                             0

因为第一个log2将根据实例2的列号进行记录,这是为了确保记录,我将第(2)列的数量乘以“\ t”和fold_change值,它会记录它没问题但是然后最后一列将是第七列,并且不会记录到七,因为最后一次写作已经完成

我非常感谢帮助人员并感谢先进!

3 个答案:

答案 0 :(得分:3)

这是我的第一个方法:

import glob
import numpy as np

with open('output.txt', 'w') as out:
    fns = glob.glob('*.txt') # Here you can change the pattern of the file (e.g. 'file_experiment_*.txt')
    # Title row:
    titles = ['gene_name', 'locus'] + [str(file + 1) + '_log2(fold_change)' for file in range(len(fns))]
    out.write('\t'.join(titles) + '\n')
    # Data row:
    data = []
    for idx, fn in enumerate(fns):
        file = np.genfromtxt(fn, skip_header=1, usecols=(2, 3, 9), dtype=np.str, autostrip=True)
        if idx == 0:
            data.extend([file[0], file[1]])
        data.append(file[2])
    out.write('\t'.join(data))

创建的文件output.txt的内容(注意:我只创建了三个用于测试的文件):

gene_name   locus   1_log2(fold_change) 2_log2(fold_change) 3_log2(fold_change)
ZZ  1:1 0   0   0

答案 1 :(得分:2)

我正在使用重新而不是 csv 。代码的主要问题是for循环,它将输出写入文件中。我正在写完整的代码。希望这能解决你遇到的问题。

import collections
import glob
import re
dicti = collections.defaultdict(list)
filetag = []

def read_data(file, base):
  with open(file, 'r') as f:
    for row in f:
      r = re.compile(r'([^\s]*)\s*')
      row = r.findall(row.strip())[:-1]
      print row
      if 'test_id' not in row[0]:
        dicti[row[2]].append((base, row))

def main():
  name_of_fold = raw_input("Folder name to stored output files in: ")
  for file in glob.glob("*.txt"):
    base=file[0:3]+"-log2(fold_change)"
    filetag.append(base)
    read_data(file, base)

  with open ("output", "w") as out:
    data = ("genename" + "\t"+  "locus" + "\t" + "\t".join(sorted(filetag))+"\n")
    r = re.compile(r'([^\s]*)\s*')
    data = r.findall(data.strip())[:-1]
    out.write('{0[1]:<30}{0[2]:<30}{0[3]:<30}{0[4]:<30}{0[5]:<30}    {0[6]:<30}{0[7]:<30}{0[8]:<30}'.format(data))
    out.write('\n')
    for key in dicti:
      print 'locus = ' + str(dicti[key][1])
      data = (key + "\t" + dicti[key][1][1][3] + "\t" + "".join([     len(z[0][0:3]) * "\t" + z[1][9]  for z in dicti[key] ])+"\n")
      data = r.findall(data.strip())[:-1]
      out.write('{0[0]:<30}{0[1]:<30}{0[2]:<30}{0[3]:<30}{0[4]:<30}{0[5]:<30}{0[6]:<30}{0[7]:<30}{0[8]:<30}'.format(data))
      out.write('\n')

if __name__ == '__main__':
  main()

并且我将输出文件的名称从output.txt更改为输出,因为前者可能会在代码考虑所有.txt文件时中断代码。而且我附加了我得到的输出,我假设你想要的格式。 感谢

gene name   locus   1.t-log2(fold_change)   2.t-log2(fold_change)    3.t-log2(fold_change)  4.t-log2(fold_change)   5.t-log2(fold_change)   6.t-log2(fold_change)   7.t-log2(fold_change)
ZZ  1:1             0           0           0           0           0           0           0

答案 2 :(得分:1)

请记住将InternetExplorer.Application附加到每行的末尾以创建换行符。这种方法非常节省内存,因为它一次只处理一行。

\n