在Python中将多列输出为两行
我正在处理一个输出列表,里面包含以下信息:
[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
任何帮助都会很棒。
5 个回答
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 函数,传入数据作为一个二维列表,还可以选择性地传入列名和行名,作为列表形式。
3
如果要把数据发送到Excel,我会选择使用CSV格式,而不是固定长度的文本格式。这样的话,如果你需要在浮点数值中显示更多的有效数字,输出的格式就不会改变。而且,CSV文件可以直接在Excel中打开,不需要导入。而且,csv.writer
会帮你处理所有的数据类型转换问题。
我还会利用一个明显的事实,就是每个观察中的第四项看起来是一组键值对,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