【问题标题】:Sort unique by several columns, then merge values in non-matching columns按几列排序唯一,然后合并不匹配列中的值
【发布时间】:2020-02-23 09:27:45
【问题描述】:

考虑一个包含遗传变异的床文件:

CHR 开始 停止 RSID REF/ALT 表型 P值
1 987654321 987654322 rs123456 A/T 高度 6E-9
1 987654321 987654322 rs123456 A/T 行程 8E-15

我想按前 5 列排序唯一,然后合并具有唯一值的列中的内容:

示例输出:

CHR 开始停止 RSID REF/ALT 表型 PVALUE
1 987654321 987654322 rs123456 A/T 高度,行程 6E-9,8E-15

这在 Python 或 Unix 中可行吗?还是我需要写一个脚本?

如果在 Python 或 Unix 中是可能的,什么函数允许我这样做?


此问题已解决 here 但从未解决。

【问题讨论】:

    标签: python unix


    【解决方案1】:

    这是执行此操作的普通 python 方式:

    from collections import defaultdict
    
    # Open both files for reading and writing
    with open("input.txt") as fin, open("output.txt", mode="w") as fout:
        grouped_columns = defaultdict(list)
    
        # Extract headers
        headers = next(fin)
    
        # Collect grouped columns in defaultdict, using first 5 columns as the key
        for line in fin:
            line = line.strip().split()
            grouped_columns[tuple(line[:5])].append(line[5:])
    
        # Write out result from dictionary
        fout.write(headers)
        for key, value in grouped_columns.items():
            fout.write(
                "%s %s"
                % (
                    " ".join(key),
                    " ".join("%s,%s" % (ptype, pval) for ptype, pval in zip(*value)),
                ) 
            )
    

    output.txt

    CHR START STOP RSID REF/ALT PHENOTYPE PVALUE
    1 987654321 987654322 rs123456 A/T Height,Stroke 6E-9,8E-15
    

    【讨论】:

      【解决方案2】:
      import pandas as pd
      data = pd.read_csv('file_name.txt',dtype={'PVALUE':'object'}, sep = ' ' )
      PVALUE = data.groupby(['CHR', 'START', 'STOP', 'RSID', 'REF/ALT'])['PVALUE'].apply(','.join).reset_index()['PVALUE']
      data = data.groupby(['CHR', 'START', 'STOP', 'RSID', 'REF/ALT'])['PHENOTYPE'].apply(','.join).reset_index()
      data['PVALUE'] = PVALUE
      print(data)
      
         CHR      START       STOP      RSID REF/ALT      PHENOTYPE      PVALUE
      0    1  987654321  987654322  rs123456     A/T  Height,Stroke  6E-9,8E-15
      

      【讨论】:

        【解决方案3】:

        Python

        使用 Python,可以使用 pandas.dataframe.groupbyagg 和自定义 lambda 函数 lambda x: ','.join(x) 来完成

        import pandas as pd
        from io import StringIO
        
        text='''CHR START STOP RSID REF/ALT PHENOTYPE PVALUE
        1 987654321 987654322 rs123456 A/T Height 6E-9
        1 987654321 987654322 rs123456 A/T Stroke 8E-15'''
        
        df = pd.read_csv(StringIO(text), sep=' ', dtype={'PVALUE': str})
        print(df)
           CHR      START       STOP      RSID REF/ALT PHENOTYPE PVALUE
        0    1  987654321  987654322  rs123456     A/T    Height   6E-9
        1    1  987654321  987654322  rs123456     A/T    Stroke  8E-15
        
        df_res = (df.groupby(['CHR', 'START', 'STOP', 'RSID', 'REF/ALT'])
                  .agg({'PHENOTYPE': lambda x: ','.join(x),
                        'PVALUE': lambda x: ','.join(x)})
                  .reset_index())
        print(df_res)
           CHR      START       STOP      RSID REF/ALT      PHENOTYPE      PVALUE
        0    1  987654321  987654322  rs123456     A/T  Height,Stroke  6E-9,8E-15
        

        使用sort_valuesdf_res 与您想要的订单进行排序。

        【讨论】:

          猜你喜欢
          • 2014-03-17
          • 1970-01-01
          • 2016-11-07
          • 2015-11-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多