我有一组500个细胞和另外一组约12个基因。我还有一本字典词典,其中包含映射到基因的细胞,以及映射到计数的基因。我想将这些信息构建成一个矩阵,其中我们将单元格作为列名称,将基因作为行名称。基因细胞的每个细胞都包含计数。如果该特定单元格没有计数编号,则用零占位符填充
这是一个玩具示例。假设您获得了这些数据:
cells = set(['cell_1', 'cell_2'])
genes = set(['gene_a', 'gene_b', 'gene_c', 'gene_d', 'gene_e', 'gene_f'])
test_data = {'cell_2': {'gene_c': 13, 'gene_f': 6},
'cell_1': {'gene_a': 12, 'gene_c': 2}}
我们想要创建一个标签分隔表,如下所示:
cell_1| cell_2
-------|------|-------
gene_a | 12 | 0
gene_b | 0 | 0
gene_c | 2 | 13
gene_d | 0 | 0
gene_e | 0 | 0
gene_f | 0 | 6
这里的最终目标是以制表符分隔格式写出这个矩阵。任何帮助将不胜感激。
答案 0 :(得分:0)
这是一个输出制表符分隔文件的解决方案:
cells = ['cell_1', 'cell_2']
genes = ['gene_a', 'gene_b', 'gene_c', 'gene_d', 'gene_e', 'gene_f']
test_data = {'cell_2': {'gene_c': 13, 'gene_f': 6},
'cell_1': {'gene_a': 12, 'gene_c': 2}}
with open("genes.csv", "w") as f:
f.write("name")
for cell in cells:
f.write("\t")
f.write(cell)
for gene in genes:
f.write("\n")
f.write(gene)
for cell in cells:
f.write("\t")
if cell in test_data and gene in test_data[cell]:
val = test_data[cell][gene]
else:
val = 0 # this could be considered an error
f.write(str(val))
该文件如下所示:
name cell_1 cell_2
gene_a 12 0
gene_b 0 0
gene_c 2 13
gene_d 0 0
gene_e 0 0
gene_f 0 6
我将细胞和基因作为列表而不是集合,以维持它们的顺序。列表或集合之间没有任何效率差异,所以如果你已经将它们作为集合,那也没关系。
我为没有数据的任何细胞/基因输出零,您可能更喜欢将其更改为空白或引发错误。
答案 1 :(得分:0)
pythonistic方式将使用列表推导。此外,通过小步骤分割过程使其易于阅读和维护。
def make_matrix(genes, cells, data):
return [[data[cell].get(gene, 0) for cell in sorted(cells)] for gene in sorted(genes)]
def add_headers(row_headers, column_headers, matrix):
annotated_matrix = [[header] + row for header, row in zip(sorted(row_headers), matrix)]
return [[""] + list(column_headers)] + annotated_matrix
def format_matrix(matrix):
return '\n'.join(['\t'.join([str(item) for item in row]) for row in matrix])
print(format_matrix(add_headers(genes, cells, make_matrix(genes, cells, test_data))))