2015-04-14 2 views
0

Dataframe:Группировка и фильтрация данных

Protein Peptide Mean intensity 
A1  AAB  4,54    
A1  ABB  5,56    
A1  ABB  4,67      
A1  AAB  5,67    
A1  ABC  5,67    
A2  ABB  4,64    
A2  AAB  4,54    
A2  ABB  5,56    
A2  ABC  4,67       
A2  ABC  5,67    

Но мне нужно найти для каждого сверху белка 2 (наиболее часто) пептидов, поэтому выход был бы для A1:

Protein Peptide Mean intensity 
A1   AAB  4,54 + 5.67/2 
      ABB  5.56 + 4.67/2 
A2   ABB  7,42 
      ABC  5,17 

Так что проблема он должен оставаться в качестве кадра данных.

+0

Cal вы объясните, пожалуйста, расчет, как вам добраться до желаемого результата? И что означает значение, например '4,54 + 5.67/2'? Очень дикое предположение: распределение с 4.54 как среднее и 5.67 как FWHM или '5.67/2' как стандартное отклонение? – Carsten

+0

Нет. Я просто имел в виду, что он вычисляет для белка A1 пептид AAB (в первой таблице он имеет два значения и просто вычисляет средства этих двух значений пептида), поэтому добавление средних значений AAB и деление на сколько AAB. Среднее значение средней интенсивности для пептида. – Maku

+0

Хорошо, получилось, но я до сих пор не понимаю, как вы получаете значение 7.42 для A2/ABB. Это опечатка? Потому что, если вам просто нужно среднее значение для каждой комбинации белка/пептида, вы можете просто называть 'df.groupby (['Protein', 'Peptide']). Mean()'. Это то, что вы хотите? – Carsten

ответ

2

Во-первых, мы можем выполнить GroupBy/применить операцию, чтобы получить белок/пептидных пар с двумя крупнейшими Пептид рассчитывает для каждого белка:

counts = (df.groupby(['Protein'])['Peptide'] 
      .apply(lambda x: x.value_counts().nlargest(2))) 
counts = counts[counts >= 2] 
counts = counts.to_frame() 
#     counts 
# Protein Peptide   
# A1  AAB   2 
#   ABB   2 
# A2  ABB   2 
#   ABC   2 

Теперь мы можем объединить оригинальную DataFrame, df с counts, путем объединения на столбцах df и индекса counts. Использование внутреннего соединения гарантирует, что только те, Protein/Пептидные пары, которые присутствуют в обоих df и counts проявляющиеся в result:

result = pd.merge(df, counts, left_on=['Protein', 'Peptide'], right_index=True, 
        how='inner') 

# Protein Peptide Mean intensity counts 
# 0  A1  AAB   4.54  2 
# 3  A1  AAB   5.67  2 
# 1  A1  ABB   5.56  2 
# 2  A1  ABB   4.67  2 
# 5  A2  ABB   4.64  2 
# 7  A2  ABB   5.56  2 
# 8  A2  ABC   4.67  2 
# 9  A2  ABC   5.67  2 

Теперь легко выполнить нужную groupby/mean операцию:

result = result.groupby(['Protein', 'Peptide'])['Mean intensity'].mean() 

Так положить все это вместе,

import pandas as pd 
df = pd.read_table('data', sep='\s{2,}') 

counts = (df.groupby(['Protein'])['Peptide'] 
      .apply(lambda x: x.value_counts().nlargest(2))) 
counts = counts[counts >= 2] 
counts = counts.to_frame() 
result = pd.merge(df, counts, left_on=['Protein', 'Peptide'], right_index=True, 
        how='inner') 
result = result.groupby(['Protein', 'Peptide'])['Mean intensity'].mean() 
result = result.reset_index() 
print(result) 

дает

Protein Peptide Mean intensity 
0  A1  AAB   5.105 
1  A1  ABB   5.115 
2  A2  ABB   5.100 
3  A2  ABC   5.170 
+0

Спасибо! Это именно то, что я искал! Хотя я и не упомянул, что мне также нужно использовать только белки, которые имеют по меньшей мере 2 разных пептида (так как некоторые из них имеют только один). Так сложно, когда вы являетесь биологом и вынуждены использовать python: D – Maku

+0

Выбор белка, который имеет по крайней мере 2 разных пептида, можно сделать с помощью 'count = count [count> = 2]'. Я отредактировал сообщение выше, чтобы показать, что я имею в виду. – unutbu

Смежные вопросы