2009-10-15 125 views
0

我有包含以下信息的輸出列表的工作:輸出兩行多列蟒蛇

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

[[59000, 59500, chr1, 
    [('cn_04', '1.362352462'), ('cn_01', '1.8020')]], 
    [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 

任何幫助將是巨大的。

+0

你試過了什麼? – SilentGhost 2009-10-15 16:57:33

回答

0

您可以創建一個擴展名爲「* .csv」的簡單文本文件。用逗號分隔每個字段(列)。或者,對文本字段使用引號,特別是如果字段需要包含您的分隔符(逗號)。你甚至可以把Excel公式(以'='開頭)和Excel將正確解析它們。

雙擊任何csv文件將在Excel中打開它(除非您的計算機有其他設置)。

您還可以使用csv module

Learning Python book包含使用Windows COM組件

編輯與更復雜的控制(格式,電子表格)的例子:我剛纔看到this site。 PDF教程似乎非常詳細。從未使用過。

0

這裏有一種方法。我做了一個簡化的假設,即可能的觀測數有一個有限的小限制,所以我只是明確地從1到6循環。您可以輕鬆擴展循環的上限,但如果超過9,get_obs函數中的邏輯將需要更改。你也可以寫一些更復雜的東西來首先掃描所有數據並獲得所有可能的觀察名稱,但是如果沒有必要,我不想投入這種努力。

如果使用字典而不是元組列表來保存每行的觀察數據,這可能會有所簡化。

data = [[59000, 59500, 'chr1', 
    [('cn_04', '1.362352462'), ('cn_01', '1.8020')]], 
    [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 
+0

我喜歡這個答案!它看起來很漂亮,正是我所需要的。非常感謝。 – 2009-10-15 17:41:01

-1

千萬不要做這些類型的嵌套列表/字典,它們不是pythonic,它們很可能會給你帶來錯誤。

相反,無論是使用一類:

>>> 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.8020')]) 
>>> 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的的recordarrays和矩陣。

要讀取和寫入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') 
+1

您的初始評論是無稽之談。嵌套列表如何「不Pythonic」?與使用Python內置功能相比,如何使用像numpy這樣的第三方庫更多的Pythonic? – 2009-10-15 18:00:09

+0

我說過,因爲我知道用戶想問什麼,爲什麼。幾年前,我遇到了同樣的情況,我可以告訴你它正在使用錯誤的方法。 在任何情況下,讀取和寫入CSV文件的標準方式都是使用csv模塊,或者使用numpy的recarrays來擴展。 使用列表的方式不pythonic,是更多的perlist,因爲在python中你有更好的數據結構來處理這些情況,你也有對象。 – dalloliogm 2009-10-16 08:22:09

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.8020')]], [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.8020,,,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 
0

您還可以使用xlwt直接寫.xls文件,而不觸及的Excel。 More info

下面是一些示例代碼,讓你開始(遠非完美):

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,以數據爲2-d列表,以及可選的行和列的名稱作爲列表。