Quelqu'un peut-il suggérer une bonne solution pour supprimer les doublons inversés d'une trame de données?

Mes données ressemblent à ceci, où les première et deuxième colonnes sont des doublons inversés.

TRINITY_DN16813_c0_g1_i3    TRINITY_DN16813_c0_g1_i4    96.491  228 8   0   202 429 417 190 3.049999999999999e-104  377
TRINITY_DN16813_c0_g1_i4    TRINITY_DN16813_c0_g1_i3    96.104  231 9   0   190 420 429 199 2.979999999999999e-104  377

Je dois garder une seule ligne, où la troisième colonne a la valeur la plus élevée

TRINITY_DN16813_c0_g1_i3    TRINITY_DN16813_c0_g1_i4    96.491  228 8   0   202 429 417 190 3.049999999999999e-104  377

C'est le résultat lorsque j'utilise series.isin ().

TRINITY_DN28139_c0_g1_i2    TRINITY_DN28139_c0_g1_i5    99.971  3465    1   0   1   3465    1   3465    0.0 6394
TRINITY_DN28139_c0_g1_i5    TRINITY_DN28139_c0_g1_i2    99.971  3465    1   0   1   3465    1   3465    0.0 6394
TRINITY_DN25313_c0_g1_i6    TRINITY_DN25313_c0_g1_i5    99.97   3315    1   0   1   3315    1   3315    0.0 6117
TRINITY_DN25313_c0_g1_i5    TRINITY_DN25313_c0_g1_i6    99.97   3315    1   0   1   3315    1   3315    0.0 6117
TRINITY_DN25502_c0_g1_i3    TRINITY_DN25502_c0_g1_i4    99.96799999999999   3078    1   0   1   3078    1   3078    0.0 5679
TRINITY_DN25502_c0_g1_i4    TRINITY_DN25502_c0_g1_i3    99.96799999999999   3078    1   0   1   3078    1   3078    0.0 5679
TRINITY_DN28726_c0_g1_i2    TRINITY_DN28726_c0_g1_i1    99.96600000000001   5805    2   0   1   5805    1   5805    0.0 10709
TRINITY_DN28726_c0_g1_i1    TRINITY_DN28726_c0_g1_i2    99.96600000000001   5805    2   0   1   5805    1   5805    0.0 10709
TRINITY_DN27942_c0_g1_i7    TRINITY_DN27942_c0_g1_i6    99.964  2760    1   0   1   2760    1   2760    0.0 5092
TRINITY_DN25118_c0_g1_i1    TRINITY_DN25118_c0_g1_i2    99.964  2770    1   0   81  2850    204 2973    0.0 5110
TRINITY_DN27942_c0_g1_i6    TRINITY_DN27942_c0_g1_i7    99.964  2760    1   0   1   2760    1   2760    0.0 5092
TRINITY_DN25118_c0_g1_i2    TRINITY_DN25118_c0_g1_i1    99.964  2770    1   0   204 2973    81  2850    0.0 5110
TRINITY_DN28502_c1_g1_i9    TRINITY_DN28502_c1_g1_i7    99.963  2678    1   0   1928    4605    2021    4698    0.0 4940
TRINITY_DN28502_c1_g1_i7    TRINITY_DN28502_c1_g1_i9    99.963  2678    1   0   2021    4698    1928    4605    0.0 4940
TRINITY_DN25619_c0_g1_i1    TRINITY_DN25619_c0_g1_i8    99.963  2715    1   0   1   2715    1   2715    0.0 5009
TRINITY_DN25619_c0_g1_i8    TRINITY_DN25619_c0_g1_i1    99.963  2715    1   0   1   2715    1   2715    0.0 5009
TRINITY_DN23022_c0_g1_i5    TRINITY_DN23022_c0_g1_i1    99.962  2622    1   0   1   2622    1   2622    0.0 4837
2
aboozar soorni 27 janv. 2019 à 12:25

3 réponses

Meilleure réponse

Essaye celui-là. C'est complètement dans les pandas (devrait être plus rapide) Cela corrige également les bugs dans ma réponse précédente mais le concept de prendre les étiquettes en paire reste le même.

In [384]: df['pair'] = df[[0, 1]].apply(lambda x: '{}-{}'.format(*sorted((x[0], x[1]))), axis=1)

Obtenez uniquement des valeurs maximales par résultat dupliqué:

In [385]: dfd = df.loc[df.groupby('pair')[2].idxmax()]

Si vous avez besoin que les noms soient dans des colonnes séparées:

In [398]: dfd[0] = dfd['pair'].transform(lambda x: x.split('-')[0])
In [399]: dfd[1] = dfd['pair'].transform(lambda x: x.split('-')[1])
1
kentwait 27 janv. 2019 à 12:50

Le problème est que les étiquettes de la colonne 0 et de la colonne 1 doivent être considérées comme une paire afin qu'un isin seul ne fonctionne pas

Tout d'abord, une liste de paires d'étiquettes est nécessaire pour comparer à (forward dans le code). Étant donné que (a,b) est identique à (b,a), toutes les instances seront simplement remplacées par (a,b)

Ensuite, toutes les étiquettes dupliquées sont renommées dans l'ordre a,b même si la ligne supérieure est b,a. Cela est nécessaire pour effectuer l'étape de regroupement ultérieurement.

In [293]: df['pair'] = df[[0, 1]].apply(l, axis=1)

Ensuite, pour tenir compte de la valeur de la colonne 2 (troisième colonne de gauche), les données d'origine sont regroupées et le min du groupe est conservé. Ce seront les lignes à supprimer.

In [297]: dfi = df.set_index(['pair',2])

In [298]: to_drop = df.groupby([0,1])[2].min().reset_index().set_index([0,1,2]).index

In [299]: dfi['drop'] = dfi.index.isin(to_drop)

In [300]: dfr = dfi.reset_index()

Les lignes sont supprimées par le numéro d'index où la colonne «drop» est True. La colonne «drop» temporaire est également supprimée.

In [301]: df_dropped = dfr.drop(np.where(dfr['drop'])[0], axis=0).drop('drop', axis=1)

In [302]: df_dropped
Out[302]:
                         0                         1       2    3   4   5    6    7    8    9              10   11
0  TRINITY_DN16813_c0_g1_i3  TRINITY_DN16813_c0_g1_i4  96.491  228   8   0  202  429  417  190  3.050000e-104  377
0
kentwait 27 janv. 2019 à 12:41

Utilisez series.isin() pour trouver les mêmes entrées dans les deux colonnes et supprimer les doublons:

df=df.sort_values('col3',ascending=False)
df.loc[df['col1'].isin(df['col2']).drop_duplicates().index]

col1 est la première colonne et col2 est la deuxième

Production:

0   TRINITY_DN16813_c0_g1_i3    TRINITY_DN16813_c0_g1_i4    96.49   228 8   0   202 429 417 190 0.00    377
1
anky_91 27 janv. 2019 à 10:18