0

我正在使用包含以下信息的输出列表:

[start position, stop position, chromosome, 
    [('sample name', 'sample value'), 
     ('sample name','sample value')...]]

[[59000, 59500, chr1, 
    [('cn_04', '1.362352462'), ('cn_01', '1.802001235')]], 
    [100000, 110000, chr1, 
        [('cn_03', '1.887268908'), ('cn_02', '1.990457407'), ('cn_01', '4.302275763')]],
    [63500, 64000, chr1, 
        [('cn_03', '1.887268908'), ('cn_02', '1.990457407'), ('cn_01', '4.302275763')]]
    ...]

我想将它写入一个 excel 文件,该文件将使用样本名称作为列的标题,然后是列中样本的值来格式化它。一些样本没有值,因此这些空格将为空白或没有数据符号。看起来像这样的东西(抱歉必须使用 >> 来表示列分离):

cn_01     cn_02     cn_03     cn_04     cn_05     cn_06    start    stop    chromosome  

1.802     ""        ""        1.362     ""        ""       59000    59500   chr1  
4.302     1.990     1.887     ""        ""        ""       100000   110000  chr1  

任何帮助都会很棒。

4

5 回答 5

3

对于向 Excel 发送数据,我会使用 CSV 而不是固定长度的文本格式;这样,如果事实证明(比如说)您的浮点值需要更多有效数字,则输出的格式不会改变。此外,您可以在 Excel 中打开 CSV 文件;您不必导入它们。并为csv.writer您处理所有数据类型转换问题。

我还将利用(明显的)事实,即每个观察中的第 4 项似乎是一组键/值对,该dict函数可以将其转换为字典。假设您知道所有键是什么,您可以指定您希望它们出现在输出中的顺序,只需将它们放在一个列表中(keys在下面的代码中调用)。然后很容易使用列表推导创建一个有序的值列表。因此:

>>> import sys
>>> import csv
>>> keys = ['cn_01', 'cn_02', 'cn_03', 'cn_04', 'cn_05', 'cn_06']
>>> data = [[59000, 59500, 'chr1', [('cn_04', '1.362352462'), ('cn_01', '1.802001235')]], [100000,   110000, 'chr1', [('cn_03', '1.887268908'), ('cn_02', '1.990457407'), ('cn_01', '4.302275763')]], [63500, 64000, 'chr1', [('cn_03', '1.887268908'), ('cn_02', '1.990457407'), ('cn_01', '4.302275763')]]]
>>> writer = csv.writer(sys.stdout)
>>> writer.writerow(keys + ['start', 'stop', 'chromosome'])
cn_01,cn_02,cn_03,cn_04,cn_05,cn_06,start,stop,chromosome
>>>>for obs in data:
        d = dict(obs[3])
        row = [d.get(k, None) for k in keys] + obs[0:3]
        writer.writerow(row)

1.802001235,,,1.362352462,,,59000,59500,chr1
4.302275763,1.990457407,1.887268908,,,,100000,110000,chr1
4.302275763,1.990457407,1.887268908,,,,63500,64000,chr1

以上将数据写入sys.stdout;要创建一个真正的 CSV 文件,您可以执行以下操作:

with open('file.csv', 'w') as f:
    writer = csv.writer(f)
    # now use the writer to write out the data
于 2009-10-15T19:06:11.630 回答
0

您可以创建一个带有“*.csv”扩展名的简单文本文件。用逗号分隔每个字段(列)。(可选)对文本字段使用引号,尤其是当字段应包含您的分隔符(逗号)时。您甚至可以输入 excel 公式(以 '=' 开头)并且 excel 会正确解析它们。

双击任何 csv 文件将在 excel 中打开它(除非您的计算机有其他设置)。

您还可以使用csv 模块

学习 Python 书包含使用 Windows COM 组件进行更复杂控制(格式化、电子表格)的示例

编辑:我刚刚看过这个网站。PDF教程似乎很详细。从来没有用过这个。

于 2009-10-15T17:07:20.323 回答
0

这是一种方法。我做了一个简化的假设,即可能的观察数量有一个小的有限限制,所以我只是明确地从 1 循环到 6。您可以轻松扩展循环的上限,但如果超过 9,则 get_obs 函数中的逻辑将需要更改。您还可以编写更复杂的东西来首先扫描所有数据并获取所有可能的观察名称,但如果没有必要,我不想付出努力。

如果您使用字典而不是元组列表来保存每行的观察数据,这可能会有所简化。

data = [[59000, 59500, 'chr1', 
    [('cn_04', '1.362352462'), ('cn_01', '1.802001235')]], 
    [100000, 110000, 'chr1', 
        [('cn_03', '1.887268908'), ('cn_02', '1.990457407'), ('cn_01', '4.302275763')]],
    [63500, 64000, 'chr1', 
        [('cn_03', '1.887268908'), ('cn_02', '1.990457407'), ('cn_01', '4.302275763')]]
  ]

def get_obs( num, obslist ):
  keyval = 'cn_0' + str(num)
  for obs in obslist:
    if obs[0] == keyval:
      return obs[1]
  return "."

for data_row in data:
  output_row = ""
  for obs in range(1,7):
    output_row += get_obs( obs, data_row[3] ) + '\t'
  output_row += str(data_row[0]) + '\t'
  output_row += str(data_row[1]) + '\t'
  output_row += str(data_row[2])
  print output_row
于 2009-10-15T17:27:17.913 回答
0

您也可以使用xlwt直接编写 .xls 文件,而无需接触 Excel。 更多信息

这是一些示例代码,可帮助您入门(远非完美):

import xlwt as xl
def list2xls(data, fn=None, col_names=None, row_names=None):
        wb = xl.Workbook()
        ws = wb.add_sheet('output')
        if col_names:
            _write_1d_list_horz(ws, 0, 1, col_names)
        if row_names:
            _write_1d_list_vert(ws, 1, 0, row_names)
        _write_matrix(ws, 1, 1, data)
        if not fn:
            fn = 'test.xls'
        wb.save(fn)
    def _write_matrix(ws, row_start, col_start, mat):
        for irow, row in enumerate(mat):
            _write_1d_list_horz(ws, irow + row_start, col_start, row)
    def _write_1d_list_horz(ws, row, col, list):
        for i, val in enumerate(list):
            ws.write(row, i + col, val)
    def _write_1d_list_vert(ws, row, col, list):
        for i, val in enumerate(list):
            ws.write(row + i, col, val)

调用 list2xls,数据作为二维列表,可选的列名和行名作为列表。

于 2009-10-16T06:31:44.170 回答
-1

永远不要做这些类型的嵌套列表/字典,它们不是 Python 的,很可能会给你带来错误。

相反,要么使用一个类:

>>> class Gene:
       def __init__(self, start, end, chromosome, transcripts):
           self.start = start
           self.end = end
           self.chromosome = chromosome
           self.transcripts = transcripts
>>> gene1 = Gene(59000, 59500, 'chr1', [('cn_04', '1.362352462'), ('cn_01', '1.802001235')])
>>> gene2 = Gene(100000, 110000, 'chr1', [('cn_03', '1.887268908'), ('cn_02', '1.990457407'), ('cn_01', '4.302275763')])
>>> genes = [gene1, gene2, ...]
>>> gene1.start
59000
>>> genes[1].start
59000

或者使用 numpy 的记录数组和矩阵。

要读取和写入 CSV 文件,您可以使用 numpy 的 recarrays 和函数。

>>> from matplotlib.mlab import csv2rec, rec2csv
>>> import numpy as np
>>> d = array([(0, 10, 'chr1', [1, 2]), (20, 30, 'chr2', [1,2])], dtype=[('start', int), ('end', int), ('chromosome', 'S8'), ('transcripts', list)])

# all values in the 'chromosome' column
>>> d['chromosome']
array(['chr1', 'chr2'], 
      dtype='|S8')

# records in which chromosome == 1
>>> d[d['chromosome'] == 'chr1']   

# print first record
>>> d[0]
(0, 10, 'chr1', [1, 2])

# save it to a csv file:
>>> rec2csv(d, 'csvfile.txt', delimiter='\t')
于 2009-10-15T17:27:30.127 回答