熊猫:过滤2列中的唯一字符串

时间:2014-04-24 14:33:39

标签: python-3.x pandas bioinformatics

我有两个DataFrame,如下所示:

Interactor 1    Interactor 2   Interaction Type
Q99459          Q14204         MI:0914(association)
Q96G01          Q14203         MI:0914(association)
P01106          Q9H0S4         MI:0914(association)
Q9HAU4          P0CG47         MI:0414(enzymatic reaction)
O95786          Q14790         MI:0915(physical association)
... (90000 rows)

Gene    UniProt ID
ABI1    Q8IZP0
ABL1    P00519
AKT1    P31749
AP2A1   O95782
AP2B1   P63010
... (244 rows)

我想做的是:

  1. 删除Interaction Typedf1列与一组部分字符串不同的所有行
  2. 删除Interactor 1Interactor 2
  3. 相同的所有行
  4. 删除Interactor 1 Interactor 2df2列中UniProt IDInteractor之内的所有行
  5. 删除所有重复的行
  6. (此处有问题)删除找到镜像交互的行,但保留一个
  7. 最后一个是问题的关键,真的;我会试着解释一下我的意思。交互对是两个Interactor 1 Interactor 2 Q123 Q456 Q456 Q123 列。删除重复的交互对(4)很容易,但不是镜像版本。例如,镜像交互对看起来像这样:

    # Read data
    input_file = 'Interaction lists/PrimesDB PPI.xlsx'
    data = pd.read_excel(input_file, sheetname='Sheet 1')
    data = data[['Interactor 1', 'Interactor 2', 'Interaction Type']]
    
    # Filter: interaction types
    data = data[data['Interaction Type'].str.contains(
        'MI:0407|MI:0915|MI:0203|MI:0217')]
    
    # Filter: self-interactions
    data = data[data['Interactor 1'] != data['Interactor 2']]
    
    # Filter: included genes
    genes = pd.read_excel('Interaction lists/PrimesDB PPI (filtered).xlsx',
        sheetname='Gene list')
    data = data[data['Interactor 1'].isin(genes['UniProt ID'])]
    data = data[data['Interactor 2'].isin(genes['UniProt ID'])]
    
    # Filter: unique interactions
    unique = data.drop_duplicates(cols=['Interactor 1', 'Interactor 2')
    

    这些,我不想要。或者,相反,我只想要其中一个,但无论哪个都没关系。我该怎么做?我有以下代码,它可以很容易地完成第(1)到第(4)点,但我无法弄清楚如何做(5)......

    {{1}}

1 个答案:

答案 0 :(得分:1)

对于第五项,删除重复对,您可以使用 DataFrame 上的选择方法尝试以下内容。它返回一个 DataFrame ,其中包含您要删除的行(假设要删除的重复项是" interctor 2"在字典上大于" intector 1"

过滤器1

#find duplicate pairs
filter = df.select(lambda x: (
                       (df['Interactor 2'] > df['Interactor 1']) &
                       (df['Interactor 2'] == df['Interactor 1'].loc[x]) & 
                       (df['Interactor 1'] == df['Interactor 2'].loc[x])
                   ).any())
#remove duplicate pairs
df.drop(filter.index, inplace=True)

在迭代较小的集合时,您将获得更好的性能,并且每行执行的工作量更少,因此将第一个比较移出循环将提高性能:

过滤器2

#find duplicate pairs
filter = (df['Interactor 2'] > df['Interactor 1']).select(lambda x: (
                       (df['Interactor 2'] == df['Interactor 1'].loc[x]) & 
                       (df['Interactor 1'] == df['Interactor 2'].loc[x])
                   ).any())
#remove duplicate pairs
df.drop(filter.index, inplace=True)

要测试,我使用this datasource

import pandas as pd
url = "http://biodev.extra.cea.fr/interoporc/files/study4932/srcInteractionsUsed.txt"
i1, i2 = 'ProteinAcA', 'ProteinAcB'
df1 = pd.read_table(url)  #1470 x 7 rows
df2 = df1.ix[:10].copy(deep=True) #11 x 7 rows
df2[i1] = df1.ix[:10][i2]
df2[i2] = df1.ix[:10][i1]
df2.index = range(1481,1492) 
df = pd.concat([df1, df2]) #1481 x 7 rows
filter = df[df[i1] > df[i2]].select(lambda x: (
                           (df[i2] == df[i1].loc[x]) & 
                           (df[i1] == df[i2].loc[x])).any() )

def FilterMirroredDuplicates(dataFrame, col1, col2):
    df = dataFrame[dataFrame[col1] > dataFrame[col2]]
    return df.select(lambda x: ((dataFrame[col2] == df[col1].loc[x]) & (dataFrame[col1] == df[col2].loc[x])).any()) 
filter = FilteredMirrorDuplicates(df, i1, i2)  #11 x 7 rows

函数 FilterMirroredDuplicates 与其上方的 select 语句相同。在此基础上,我确实发现上面的过滤器2 并没有生成要删除的适当索引集。上述陈述或函数都可以解决您的问题。

请注意,使用选择 O (n ^ 2)。但我无法想出更好的方法来执行此检查。