python - 查找并删除具有由第三个唯一特征标识的两个相同特征的重复数据条目

标签 python pandas

因此,我使用此代码来打印主序列中表示为 SOURCE 的子序列的开始和停止位置。主序列由GENE识别。 GENE 中的某些序列具有 DIRECTION 的两个组成部分:+ 和 -,并且这些序列被视为唯一序列。然而,我没有意识到的是,在首先生成数据集时(通过将许多源序列的文件与基因序列对齐),我有多个实例,其中存在源序列的多个“有效”比对针对基因序列。我需要一种方法来删除 SOURCE 序列中 GENE 序列中出现次数最少的条目,或者在 SOURCE 序列数量相同的情况下删除 POS1 到最终 POS2 范围最小的条目。我在下面有一个示例输出,其中包含一个澄清的示例。

这是我的 Python 代码:

import pandas
import pandas as pd
import sys
import csv

##sys.stdout = open("Sampletest2d.txt", "w")
##data = pd.read_csv('Sampletest2.txt', sep='\t')
sys.stdout = open("ExonFileTry1Part3.txt", "w")
data = pd.read_csv('ExonFileTry1.txt', sep='\t')
groups = data.groupby(['GENE', 'DIRECTION'])

fixedgroups = []

for (gene_id, strand), group in groups:
    #print gene_id, strand
    if strand == '+':
        group['POS-1'] = group.POS1
        group['POS-2'] = group.POS2
    else:
        group['POS-1'] = group.POS2
        group['POS-2'] = group.POS1
    #print group
    fixedgroups.append(group)
print fixedgroups

数据集(制表符分隔)

GENE    DIRECTION   POS1    POS2    SOURCE
TT-1    +   1   16  A1
TT-1    +   130 289 A1
TT-1    +   353 438 A1
TT-1    +   519 580 A1
TT-1    +   665 742 A1
TT-1    +   813 864 A1
TT-1    +   931 975 A1
TT-1    +   1053    1166    A1
TT-1    +   1   16  B2
TT-1    +   130 289 B2
TT-1    +   353 438 B2
TT-1    +   519 580 B2
TT-1    +   665 742 B2
TT-1    +   813 864 B2
TT-1    +   931 975 B2
TT-1    +   1053    1161    B2
BB-2    +   3   659 C3
BB-2    +   3   640 D4
BB-2    -   1093    426 E5
BB-2    -   1093    508 F6
EE-3    +   1   95  G7
EE-3    +   155 377 G7
EE-3    +   439 513 G7
EE-3    +   577 840 G7
EE-3    +   1   95  H8
EE-3    +   155 377 H8
EE-3    +   439 513 H8
EE-3    -   840 577 I9
EE-3    -   513 439 I9
EE-3    -   377 155 I9
EE-3    -   840 577 J10
EE-3    -   513 458 J10

有时,一个基因具有多个源序列,并且来自一个源的序列比另一个源的序列多。但是,有时来自两个不同 SOURCE 的序列数量相同,在这种情况下,我需要保留该 SOURCE 的第一个 POS1 和最后一个 POS2 之间具有最大值范围的 SOURCE。

例如,在+ D​​IRECTION中的GENE TT-1中,有两个SOURCE集A1和B2,它们都有8个条目。但是,SOURCE A1 的最终 POS2 为 1166,而 B2 的最终 POS2 为 1161,因此 B2 的范围较小,应删除。

我花了难以置信的时间来理解如何做我已经做过的事情,并且这是基于类似的代码开始的。我觉得我知道我想在这里做什么,但我只是不知道语法,因为我的计算机科学知识极其有限。感谢您提前提供的任何帮助!

最佳答案

以下是 @D.A. 答案的变体:

首先,一些样板设置:

import pandas as pd
import io

data = '''\
GENE    DIRECTION   POS1    POS2    SOURCE
TT-1    +   1   16  A1
TT-1    +   130 289 A1
TT-1    +   353 438 A1
TT-1    +   519 580 A1
TT-1    +   665 742 A1
TT-1    +   813 864 A1
TT-1    +   931 975 A1
TT-1    +   1053    1166    A1
TT-1    +   1   16  B2
TT-1    +   130 289 B2
TT-1    +   353 438 B2
TT-1    +   519 580 B2
TT-1    +   665 742 B2
TT-1    +   813 864 B2
TT-1    +   931 975 B2
TT-1    +   1053    1161    B2
BB-2    +   3   659 C3
BB-2    +   3   640 D4
BB-2    -   1093    426 E5
BB-2    -   1093    508 F6
EE-3    +   1   95  G7
EE-3    +   155 377 G7
EE-3    +   439 513 G7
EE-3    +   577 840 G7
EE-3    +   1   95  H8
EE-3    +   155 377 H8
EE-3    +   439 513 H8
EE-3    -   840 577 I9
EE-3    -   513 439 I9
EE-3    -   377 155 I9
EE-3    -   840 577 J10
EE-3    -   513 458 J10'''

df = pd.read_table(io.BytesIO(data), sep='\t')

现在我们添加 RANGESUMRANGE 列,就像 @D.A.做了:

df['RANGE'] = abs(df['POS2']-df['POS1'])
df['SUMRANGE'] = df.groupby(["GENE", "DIRECTION", "SOURCE"])['RANGE'].cumsum()
print(df)
#     GENE DIRECTION  POS1  POS2 SOURCE  RANGE  SUMRANGE
# 0   TT-1         +     1    16     A1     15        15
# 1   TT-1         +   130   289     A1    159       174
# 2   TT-1         +   353   438     A1     85       259
# 3   TT-1         +   519   580     A1     61       320
# 4   TT-1         +   665   742     A1     77       397
# 5   TT-1         +   813   864     A1     51       448
# 6   TT-1         +   931   975     A1     44       492
# 7   TT-1         +  1053  1166     A1    113       605
# 8   TT-1         +     1    16     B2     15        15
# 9   TT-1         +   130   289     B2    159       174
# 10  TT-1         +   353   438     B2     85       259
# 11  TT-1         +   519   580     B2     61       320
# 12  TT-1         +   665   742     B2     77       397
# 13  TT-1         +   813   864     B2     51       448
# 14  TT-1         +   931   975     B2     44       492
# 15  TT-1         +  1053  1161     B2    108       600
# 16  BB-2         +     3   659     C3    656       656
# 17  BB-2         +     3   640     D4    637       637
# 18  BB-2         -  1093   426     E5    667       667
# 19  BB-2         -  1093   508     F6    585       585
# 20  EE-3         +     1    95     G7     94        94
# 21  EE-3         +   155   377     G7    222       316
# 22  EE-3         +   439   513     G7     74       390
# 23  EE-3         +   577   840     G7    263       653
# 24  EE-3         +     1    95     H8     94        94
# 25  EE-3         +   155   377     H8    222       316
# 26  EE-3         +   439   513     H8     74       390
# 27  EE-3         -   840   577     I9    263       263
# 28  EE-3         -   513   439     I9     74       337
# 29  EE-3         -   377   155     I9    222       559
# 30  EE-3         -   840   577    J10    263       263
# 31  EE-3         -   513   458    J10     55       318

对于每个具有共同GENE和DIRECTION的组,记录具有最大SUMRANGE的行的索引:

idx = df.groupby(["GENE", "DIRECTION"])['SUMRANGE'].agg(lambda col: col.idxmax())
print(idx)
# GENE  DIRECTION
# BB-2  +            16
#       -            18
# EE-3  +            23
#       -            29
# TT-1  +             7
# Name: SUMRANGE

选择 df 的子 DataFrame,其中包含 GENE、DIRECTION 和 SOURCE 列以及由 idx 指定的行:

dfm = df.ix[idx, ['GENE','DIRECTION','SOURCE']]
print(dfm)
#     GENE DIRECTION SOURCE
# 16  BB-2         +     C3
# 18  BB-2         -     E5
# 23  EE-3         +     G7
# 29  EE-3         -     I9
# 7   TT-1         +     A1

dfdfm 进行内部合并。键是 dfdfm 公共(public)列的交集——即 GENE、DIRECTION 和 SOURCE。 “内部”合并仅保留 dfdfm 共享相同键的行。因此,在生成的合并 DataFrame 中,df 的 GENE、DIRECTION 和 SOURCE 必须与 dfm 的 GENE、DIRECTION 和 SOURCE 匹配。因此,所有具有错误 SOURCE 的行都会被删除:

result = pd.merge(df, dfm, how = 'inner')
print(result)
#     GENE DIRECTION  POS1  POS2 SOURCE  RANGE  SUMRANGE
# 0   TT-1         +     1    16     A1     15        15
# 1   TT-1         +   130   289     A1    159       174
# 2   TT-1         +   353   438     A1     85       259
# 3   TT-1         +   519   580     A1     61       320
# 4   TT-1         +   665   742     A1     77       397
# 5   TT-1         +   813   864     A1     51       448
# 6   TT-1         +   931   975     A1     44       492
# 7   TT-1         +  1053  1166     A1    113       605
# 8   BB-2         +     3   659     C3    656       656
# 9   BB-2         -  1093   426     E5    667       667
# 10  EE-3         +     1    95     G7     94        94
# 11  EE-3         +   155   377     G7    222       316
# 12  EE-3         +   439   513     G7     74       390
# 13  EE-3         +   577   840     G7    263       653
# 14  EE-3         -   840   577     I9    263       263
# 15  EE-3         -   513   439     I9     74       337
# 16  EE-3         -   377   155     I9    222       559

关于python - 查找并删除具有由第三个唯一特征标识的两个相同特征的重复数据条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15112677/

相关文章:

python - Pandas groupby 并将函数应用于数字列

pandas - 在具有空值但没有nan的elasticsearch中索引 Pandas 数据框

python - 将 ID 与 Pandas DataFrame 上的名称匹配

python - 批量运行python脚本..如何在结束时关闭cmd窗口?

python - Pandas 无法将 "||"识别为要拆分的字符串

python - Pandas:连接数据框中的两列(不创建两列)

Pandas 分类类型不起作用

python - 如何将 pandas 数据透视表转换为 JSON

python - 如何遍历 Python unittest runner 的所有成功测试结果?

python - 在扭曲中使用我自己的主循环