У меня два DataFrames:
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)
Я хочу сделать следующее:
- Удалите все строки, где столбец
Interaction Type
вdf1
отличается от набора частичных строк - Удалите все строки, где
Interactor 1
совпадает сInteractor 2
- Удалите любые строки, в которых любой из
Interactor 1
илиInteractor 2
НЕ находится вdf2
UniProt ID
df2
UniProt ID
df2
- Удалите все повторяющиеся строки
- (Проблема здесь) Удалите строки, в которых обнаружено зеркальное взаимодействие, но сохраняйте один
На самом деле, последняя проблема – проблема. Я попытаюсь объяснить, что я имею в виду. Пара взаимодействует с двумя столбцами Interactor
. Удаление повторяющихся пар взаимодействий (4) легко, но не зеркальные версии. Например, зеркальная пара взаимодействий будет выглядеть так:
Interactor 1 Interactor 2
Q123 Q456
Q456 Q123
Этого я не хочу. Или, скорее, я хочу только ОДИН из них, но неважно, что. Как мне это сделать? У меня есть следующий код, который делает точки (1) – (4) достаточно легко, но я не могу понять, как это сделать (5)…
# 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')
Для вашего пятого элемента, удаляя повторяющиеся пары, вы можете попробовать что-то вроде следующего, используя метод select в DataFrame. Он возвращает DataFrame, содержащий строку, которую вы хотите удалить (при условии, что дубликаты, которые вы хотите удалить, где “интерактор 2” лексикографически больше, чем “интерактор 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)
Чтобы проверить, я использую этот источник данных.
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 не генерирует соответствующий набор индексов. Вышеупомянутая формулировка или функция должны решить вашу проблему.
Имейте в виду, что использование select – O (n ^ 2). Но я не могу придумать никаких лучших средств для выполнения этой проверки.