重新排列 .tsv 文件中的单元格

Rearranging cells in a .tsv file

我附上了一个 .tsv 文件 post。我有 A1,A2,A3...A12 , B1..B2, .... H1..H12 格式的行(单元格)。我需要将其重新排列为 A1,B1,C1,D1,...H1 , A2,B2,C2,...H2 ..... A12,B12,C12,...H12 等格式。 我需要使用 Python.

来做到这一点

我有另一个 .tsv 文件,可以将它与这个文件进行比较。它被称为 flipped.tsv 。 flipped.tsv 文件包含与细胞对应的准确孔值。换句话说,我必须用它们准确的细胞系映射孔值。

据我了解,元数据的单元格行在列优先中排列不正确,而它必须以行优先格式排列,就像它在 flipped.tsv 文件中一样.

例如: “flipped_metadata.tsv 的 A2 与 metadata.tsv 的 B1 具有相同的孔值。”

在 Python 中执行此操作的逻辑是什么?

First .tsv file flipped .tsv file

您可以执行以下操作:

import csv

# Read original file
with open("file.tsv", "r") as file:
    rows = list(csv.reader(file, delimiter="\t"))

# Key function for sorting
def key_func(row):
    """ Transform row in sort key, e.g. ['A7', 1, 2] -> (7, 'A') """
    return int(row[0][1:]), row[0][0]

# Write `flipped´ file
with open("file_flipped.tsv", "w") as file:
    csv.writer(file, delimiter="\t").writerows(
        row[:1] + flipped[1:]
        for row, flipped in zip(rows, sorted(rows, key=key_func))
    )

翻转是通过

对原始行进行排序来完成的
  • 首先是他们第一行条目的整数部分 int(row[0][1:]),然后
  • 然后是他们第一个条目的字符部分 row[0][0]

参见 tio.run illustration here

如果排序的效果不明显,请看一下相同操作的结果,只是没有重新标记第一列:

with open("file_flipped.tsv", "w") as file:
    csv.writer(file, delimiter="\t").writerows(
        sorted(rows, key=key_func)
    )

输出:

A1  26403   23273
B1  27792   8805
C1  5668    19510
...
F12 100 28583
G12 18707   14889
H12 13544   7447

块首先基于数字部分构建,每个块内的行 运行 通过排序的字符。


这仅在 non-number 部分总是 恰好有一个字符时有效。

如果non-number部分有总是恰好2个字符,那么关键功能的return必须调整为int(row[0][2:]), row[0][:2]等.

如果允许更多的可变性,例如介于 1 到 5 个字符之间,那么 regex 方法会更合适:

import re

re_key = re.compile(r"([a-zA-Z]+)(\d+)")

def key_func(row):
    """ Transform row in sort key, e.g. ['Aa7', 10, 20] -> (7, 2, 'Aa') """
    word, number = re_key.match(row[0]).group(1, 2)
    return int(number), len(word), word

这是一个 regex demo

并且,根据单词的排序方式,可能需要将单词的长度包含在排序键中:Python 自然排序 ['B', 'AA', 'A'] 变成 ['A', 'AA', 'B'] 而不是 ['A', 'B', 'AA']。增加长度,就像在函数中一样,确实实现了这一点。