2016-11-11 7 views
1

重複するサンプル(_2で終わる)と元のサンプルの詳細を示す同じ列を含むサンプル列を持つデータフレームがあります。新しいカテゴリーにはPathogenic/Likely Pathogenicが最も有害で、Likely Benignが最も被害が少ない突然変異型が含まれています。以下は私のデータフレームの縮小版/基本版を示しています。条件付きで行を削除すると、パンダで意図したとおりに動作しません

df = pd.DataFrame(columns=['Sample', 'same','New Category'], 
      data=[ 
        ['HG_12_34', 'HG_12_34', 'Pathogenic/Likely Pathogenic'], 
        ['HG_12_34_2', 'HG_12_34', 'Likely Benign'], 
        ['KD_89_9', 'KD_89_9', 'Likely Benign'], 
        ['KD_98_9_2', 'KD_89_9', 'Likely Benign'], 
        ['LG_3_45', 'LG_3_45', 'Likely Benign'], 
        ['LG_3_45_2', 'LG_3_45', 'VUS'] 
        ]) 

私は条件付きサンプルまたは1つのサンプルは、おそらく良性あり、重複はその後、病原性/ Likley病原性の変異体を持っている場合は、1つは、新しいカテゴリIEで最も有害な変異を持っているかに応じてその複製のいずれかを削除したいIサンプル行を削除/削除したい

私は、削除しようとする行を表すインデックスのリストを返す関数にデータフレームを渡し、その後削除しました。

def get_unwanted_duplicates_ix(df): 

    # filter df for samples that have a duplicate 
    same_only = df.groupby("same").filter(lambda x: len(x) > 1) 

    list_index_to_delete = [] 


    for num in range(0,same_only.shape[0]-1): 

     row1 = same_only.irow(num) 
     row2 = same_only.irow(num+1) 
     index = list(same_only.index.values)[num] 



     if row1['Sample']+"_2" == row2['Sample'] or \ 
      row1['Sample'] == row2['Sample']+"_2": 

      if row1['New Category'] == row2['New Category']: 
       list_index_to_delete.append(index+1) 

      elif row1['New Category'] == "Pathogenic/Likely Pathogenic" \ 
       and row2['New Category'] != "Pathogenic/Likely Pathogenic": 
       list_index_to_delete.append(index+1) 

      elif row2['New Category'] == "Pathogenic/Likely Pathogenic" \ 
       and row1['New Category'] != "Pathogenic/Likely Pathogenic": 
       list_index_to_delete.append(index) 

      elif row1['New Category'] == "VUS" \ 
       and row2['New Category'] != "VUS": 
       list_index_to_delete.append(index+1) 

      elif row2['New Category'] == "VUS" \ 
       and row1['New Category'] != "VUS": 
       list_index_to_delete.append(index) 

      elif row1['New Category'] == 'Likely Benign' \ 
       and row2['New Category'] == 'Likely Benign': 
       list_index_to_delete.append(index+1) 

      else: 
       list_index_to_delete.append(index+1) 

    return list_index_to_delete 

unwanted = get_unwanted_duplicates_ix(df) 
df = df.drop(df.index[unwanted]) 

上記の機能は混乱しており、意外なことに、私が望むように機能しません。正しい方向のポイントが最も高く評価されます。

答えて

2

最初に、突然変異の重大度を整数に置き換えます(値が大きいほど値が大きくなります)。

df['New Category code'] = df['New Category'].replace(
    {'Likely Benign': 1, 'VUS': 2, 'Pathogenic/Likely Pathogenic': 3}) 

次のコマンドは、同じ重大度の複数の行を保持するかどうかによって異なります。 same列ではい、そのグループの場合と最大重大度コードを持つ行を選択:なし(常に各グループに一つだけの行を保つ)、その後、代わりに重症度によって昇順値をソートしないと最後を取る場合

df[df.groupby('same')['New Category code'].transform(max) == df['New Category code']]     

     Sample  same     New Category New Category code 
0 HG_12_34 HG_12_34 Pathogenic/Likely Pathogenic     3 
2 KD_89_9 KD_89_9     Likely Benign     1 
3 KD_98_9_2 KD_89_9     Likely Benign     1 
5 LG_3_45_2 LG_3_45       VUS     2 

を各グループの行(感謝@JonClementsのアイデア):

df.sort_values('New Category code').groupby('same').last() 

      Sample     New Category New Category code 
same                 
HG_12_34 HG_12_34 Pathogenic/Likely Pathogenic     3 
KD_89_9 KD_98_9_2     Likely Benign     1 
LG_3_45 LG_3_45_2       VUS     2 
+0

それはあなたが欲しいもの、またはあなたは '同じ列ではなくグループ化したいですか?そうでない場合は、質問に希望の出力を追加してください。 –

+1

私は、最大値(2つ以上の最大値を持つグループは複数のサンプルを返す)を変換して比較する代わりに、新しいカテゴリコードを降順でソートし、 'groupby( 'same')を適用することをお勧めします。 ) '代わりに...(または昇順に並べ替えてから' .last() 'を適用してください) –

+0

@JonClementsありがとう、答えを更新しました。 –

関連する問題