8
votes

Quel est le moyen le plus efficace de supprimer un groupe d'indices d'une liste de nombres à Python 2.7?

Alors je me demandais comment je peux, en utilisant Python 2.7, prenez plus efficacement une liste de valeurs utilisées pour représenter des indices comme celui-ci: (mais avec une longueur maximale de 250 000 +) xxx pré>

et supprimez cette liste d'indices d'une liste plus grande comme suit: (3 000 000 articles) p> xxx pré>

pour obtenir un résultat comme celui-ci: P>

[2, 6, 20, 42, 51]


6 commentaires

Qu'essayez-vous de supprimer?


Voulez-vous modifier la liste en place ou créer une nouvelle liste ou peu importe?


Voir cette question: Stackoverflow.com/questions/6486450/...


@voscausa: Cela élimine les éléments par valeur, pas par index


@EngineFree Chaque élément de la liste appelée indices représente un index de la liste ci-dessous. Donc, j'essaie de supprimer des chiffres [2] [4] et des chiffres [5] des chiffres.


@Foglebird ça n'a pas d'importance. Tant que c'est efficace.


6 Réponses :


4
votes

Une autre option: xxx

edit:

Donc, après avoir été désespérément trompé sur cette réponse, j'ai comparé chacune des différentes approches:

Entrez la description de l'image ici

Axe horizontal est Nombre d'articles , la verticale est l'heure en secondes.

L'option la plus rapide utilise la tranchée pour créer une nouvelle liste (à partir de @gnibbler): xxx

étonnamment et " Définit "(@ eric) Beat numpy.delete (@jon Clements)

Voici Le script que j'ai utilisé , j'ai peut-être manqué quelque chose.


2 commentaires

Considérez que chaque opération del redimensionne la liste.


@Joncensions, une matrice intéressante masquée semblent performer mal.



3
votes

Voici ma première approche.

def remove_indices(numbers, indices):
    return [numbers[i] for i in xrange(len(numbers)) if i not in indices]


3 commentaires

Merci d'avoir testé tous ceux-ci. À l'heure actuelle, cela semble être le meilleur itinéraire pour aller.


Je vais attendre un peu de temps pour voir si une autre solution apparaît.


Pouvez-vous essayer ma réponse sur votre ordinateur portable?



7
votes

Vous voudrez peut-être envisager d'utiliser l'utilisation de Bibliothèque Numpy pour l'efficacité (laquelle si vous traitez avec des listes de Les entiers peuvent ne pas être une mauvaise idée de toute façon): xxx

notes sur np.delete : http://docs.scipy.org/doc/numpy/reference/generated/numpy.delete.html

Cela pourrait également valoir la peine d'envisager de garder le tableau principal, mais de maintenir un tableau masqué (n'a pas fait de test de vitesse à ce que ...)


4 commentaires

J'ai testé cela en utilisant ma suite de test dans ma réponse et ce n'est pas significativement plus rapide qu'une compréhension de la liste. (0.53 secondes contre 0,59 secondes)


La dernière fois que j'ai essayé d'installer numpy, je n'ai pas pu trouver une version 64 bits pour Mac OS X Lion. Seulement 32 bits. Et je préférerais vraiment utiliser 64 bits. Je pourrais toutefois avoir tord. Ils peuvent avoir une construction de 64 bits que je n'ai pas vue.


@Stevenhicken pourrait aussi valoir la peine d'être regardé par des tableaux masqués


Je viens de regarder des tableaux masqués. Ils peuvent être utilisés mais je devrais redéfinir l'algorithme que je travaille.



2
votes

pas si efficace, mais une approche différente xxx


1 commentaires

C'est comme ça que je le ferais. Il a l'avantage supplémentaire de ne pas nécessiter une dépendance externe.



6
votes

Je soupçonne que prendre des tranches entières entre les indices pourrait être plus rapide que la compréhension de la liste

def remove_indices(numbers, indices):
    result = []
    i=0
    for j in sorted(indices):
        result += numbers[i:j]
        i = j+1
    result += numbers[i:]
    return result


10 commentaires

Bon point réellement. En outre, la méthode triée () est-elle nécessaire dans la boucle pour la boucle? les indices sont déjà triés. Je n'ai pas utilisé Python dans un moment alors peut-être que je ne reçois pas quelque chose.


En outre, je suis sur le point de le tester.


Beaucoup plus rapide ... 0,15 secondes.


Je suis considéré comme ça aussi mais était trop paresseux pour l'essayer. Bien fait!


@Stevenhicken, vous n'avez pas besoin du type () si des indices sont toujours déjà triés. Cela ne fera pas beaucoup de mal à le laisser, car Timsort est linéaire sur une liste préservée.


C'est une bonne quantité plus rapide que la solution de Foglebird. Je ne pouvais pas sembler avoir sa fonction améliorée pour travailler, mais son original a pris 1,05 seconde et que le vôtre a pris 0,75 seconde sur mon ordinateur portable.


@Stevenhicken: Mon amélioré supposait que les indices étaient déjà un ensemble.


Dans tous les cas, le gnibbler est toujours plus rapide.


J'ai ajouté un graphique avec des repères de différentes options, c'est de loin le meilleur.


@Foglebird qui ferait beaucoup plus de sens. Pas étonnant que je ne pouvais pas le faire travailler.



1
votes

Une autre approche différente pour atteindre cet objectif:

>>> numbers = [2, 6, 12, 20, 24, 40, 42, 51]
>>> indices = [2, 4, 5]
>>> [item for item in numbers if numbers.index(item) not in indices]
[2, 6, 20, 42, 51]


0 commentaires