【问题标题】:Split a row into multiple cells and keep the maximum value of second value for each gene将一行拆分为多个单元格,并为每个基因保留第二个值的最大值
【发布时间】:2023-04-02 22:54:01
【问题描述】:

我是 Python 新手,我准备了一个脚本,将修改以下 csv file

因此:

1) 每行包含多个 Gene 条目,以/// 分隔,如:

C16orf52 /// LOC102725138 1.00551

应该转化为:

C16orf52 1.00551  
LOC102725138 1.00551

2) 同一个基因可能有不同的比值

AASDHPPT 0.860705  
AASDHPPT 0.983691  

我们只想保留比率值最高的对(删除对AASDHPPT 0.860705

这是我编写的脚本,但它没有为基因分配正确的比率值:

import csv
import pandas as pd

with open('2column.csv','rb') as f:
    reader = csv.reader(f)
    a = list(reader)
gene = []
ratio = []
for t in range(len(a)):
    if '///' in a[t][0]:
        s = a[t][0].split('///')
        gene.append(s[0])
        gene.append(s[1])
        ratio.append(a[t][1])
        ratio.append(a[t][1])
    else:
        gene.append(a[t][0])
        ratio.append(a[t][1])
    gene[t] = gene[t].strip()

newgene = []
newratio = []
for i in range(len(gene)):
    g = gene[i]
    r = ratio[i]
    if g not in newgene:
        newgene.append(g)
    for j in range(i+1,len(gene)):
        if g==gene[j]:
            if ratio[j]>r:
                r = ratio[j]
    newratio.append(r)

for i in range(len(newgene)):
    print newgene[i] + '\t' + newratio[i]

if len(newgene) > len(set(newgene)):
    print 'missionfailed'   

非常感谢您的任何帮助或建议。

【问题讨论】:

标签: python arrays csv optimization


【解决方案1】:

试试这个:

with open('2column.csv') as f:
    lines = f.read().splitlines()

new_lines = {}
for line in lines:
    cols = line.split(',')
    for part in cols[0].split('///'):
        part = part.strip()
        if not part in new_lines:
            new_lines[part] = cols[1]
        else:
            if float(cols[1]) > float(new_lines[part]):
                new_lines[part] = cols[1]


import csv
with open('clean_2column.csv', 'wb') as csvfile:
    writer = csv.writer(csvfile, delimiter=' ',
                            quotechar='|', quoting=csv.QUOTE_MINIMAL)
    for k, v in new_lines.items():
        writer.writerow([k, v])

【讨论】:

  • 感谢您的帮助。但是,出现了以下错误: Traceback (last recent call last): File "gsea.py", line 10, in new_lines[part] = cols[1] IndexError: list index out of range 你有什么建议?
  • 这可能是因为您在与您共享的文件不同的 csv 文件上进行了测试。 (检查是否有相同的分隔符,
【解决方案2】:

这应该可行。

它使用彼得的字典建议。

import csv

with open('2column.csv','r') as f:
    reader = csv.reader(f)
    original_file = list(reader)
    # gets rid of the header 
    original_file = original_file[1:]

# create an empty dictionary 
genes_ratio = {}

# loop over every row in the original file
for row in original_file:
    gene_name = row[0]
    gene_ratio = row[1]
    # check if /// is in the string if so split the string
    if '///' in gene_name:
        gene_names = gene_name.split('///')
        # loop over all the resulting compontents
        for gene in gene_names:
            # check if the component is in the dictionary 
            # if not in dictionary set value to gene_ratio
            if gene not in genes_ratio:
                genes_ratio[gene] = gene_ratio
            # if in dictionary compare value in dictionary to gene_ratio
            # if dictionary value is smaller overwrite value
            elif genes_ratio[gene] < gene_ratio:
                genes_ratio[gene] = gene_ratio
    else:
        if gene_name not in genes_ratio:
            genes_ratio[gene_name] = gene_ratio
        elif genes_ratio[gene_name] < gene_ratio:
            genes_ratio[gene_name] = gene_ratio

#loop over dictionary and print gene names and their ratio values 
for key in genes_ratio:
    print key, genes_ratio[key]

【讨论】:

    【解决方案3】:

    首先,如果您要导入 Pandas,请知道您有 I/O Tools 来读取 CSV 文件。

    首先,让我们以这种方式导入它:

    df = pd.read_csv('2column.csv')
    

    然后,您可以提取具有“///”模式的索引:

    l = list(df[df['Gene Symbol'].str.contains('///')].index)
    

    然后,您可以创建新行:

    for i in l :
        for sub in df['Gene Symbol'][i].split('///') : 
             df=df.append(pd.DataFrame([[sub, df['Ratio(ifna vs. ctrl)'][i]]], columns = df.columns))
    

    然后,删除旧的:

    df=df.drop(df.index[l])
    

    然后,我将做一个小技巧来删除您的最低重复值。首先,我将按“比率(ifna 与 ctrl)”对它们进行排序,然后我将 drop all the duplicates 但第一个:

    df = df.sort('Ratio(ifna vs. ctrl)', ascending=False).drop_duplicates('Gene Symbol', keep='first')
    

    如果您想保持按基因符号排序并将索引重置为更简单的索引,只需执行以下操作:

    df = df.sort('Gene Symbol').reset_index(drop=True)
    

    如果您想将修改后的数据重新导出到 csv,请执行以下操作:

    df.to_csv('2column.csv')
    

    编辑:我编辑了我的答案以纠正语法错误,我已经用你的 csv 测试了这个解决方案,它工作得很好:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-02
      • 2020-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      相关资源
      最近更新 更多