Pandas 单列计数文件的数据框 manipulation/re-sizing

Pandas dataframe manipulation/re-sizing of a single-column count file

我有一个如下所示的文件:

gRNA_A
gene_a
140626
gene_b
227598
gene_c
115781
gRNA_B
gene_a
125003
gene_b
102000
gene_c
200300

我想将其读入 pandas 数据框并重新塑造它,使其看起来像这样:

        gene_a gene_b gene_c
gRNA_A  140626 227598 115781
gRNA_B  125003 102000 200300

这可能吗?如果可以,怎么做?

注意:它不会总是这个大小,因此解决方案需要与大小无关。输入文件最多为 ~200gRNA x 20genes。会有 gRNA_somelettercombos,但基因不会被命名 gene_lettercombo-- 基因将是实际基因的名称(如 GAPDH、ACTB 等)。

您需要为您的自定义格式编写一个解析器,依靠gRNA 字符串开始一个新组,然后将奇数元素作为键,偶数元素作为值:

d = {}
current_rRNA = None
gene = None

with open('gRNA.txt') as f:
    for line in f:                    # iterate over lines
        line = line.strip()
        if not line:                  # skip blank lines
            continue
        if line.startswith('gRNA_'):  # start new group
            current_rRNA = line
            d[current_rRNA] = {}
        else:
            if gene:                  # even line of a group = data
                d[current_rRNA][gene] = int(line)
                gene = None
            else:                     # odd line of a group = gene name
                gene = line

df = pd.DataFrame.from_dict(d, orient='index')

输出:

        gene_a  gene_b  gene_c
gRNA_A  140626  227598  115781
gRNA_B  125003  102000  200300

不确定这是否是最干净的方法,但这适用于给定的示例。

我使用提供的示例创建了一个文件 data.txt

我假设计数始终是一个数字。

def file_parser(f_path):
    data_dict = {}
    my_gRNA = None
    my_gene = None
    with open(f_path, "r") as f:
        for each in f:
            if not each:
                continue
            each = each.strip()
            if each.startswith("gRNA"):
                if each not in data_dict:
                    data_dict[each] = {}
                my_gRNA = each
            elif not each.isnumeric() and isinstance(each, str) and not each.startswith("gRNA"):
                my_gene = each
            elif each.isnumeric():
                data_dict[my_gRNA][my_gene] = each
        return data_dict
    

df = pd.DataFrame.from_dict(file_parser("data.txt"), orient='index')
df.head()
        gene_a  gene_b  gene_c
gRNA_A  140626  227598  115781
gRNA_B  125003  102000  200300

注意:这个答案与 mozway 的答案非常相似。唯一的区别在于解析器,我在解析器中明确检查数字类型。