2 votes

Supprimer les coordonnées des listes sur Python

Il s'agit d'une question de suivi de ma dernière question : Python3 Numpy np.where Erreur .

J'ai deux listes comme celle-ci :

x = [None,[1, 15, 175, 20],
    [150, 175, 18, 20],
    [150, 175, 18],
    [192, 150, 177],...]

y = [None,[12, 43, 55, 231],
    [243, 334, 44, 12],
    [656, 145, 138],
    [12, 150, 177],
    [150, 177, 188],...]

Je veux enlever le x inférieures à 30 et y qui correspondent aux valeurs supprimées x valeurs. (Par exemple, (x,y) = (1,12) en x[1] y y[1] )

Pour ce faire, j'ai obtenu le corrigé x liste :

In : [[v2 for v2 in v1 if v2>=30] for v1 in x[1:]]
Out: [[175], [150, 175], [150, 175], [192, 150, 177]]

J'ai également obtenu les coordonnées des autres x valeurs :

In : [(i,j) for i,v1 in enumerate(x[1:]) for j,v2 in enumerate(v1) if v2<30]
Out: [(0, 0), (0, 1), (0, 3), (1, 2), (1, 3), (2, 2)]

Maintenant, je veux utiliser ces coordonnées pour retirer des éléments de la liste de l'UE. y .

Comment puis-je mettre cela en œuvre ?

1voto

Don Thousand Points 1032
new_y = []
for i in range(len(y)):
    new_y.append([y[i][j] for j in range(len(y[i])) if (i,j) not in BadList])

donde BadList est

[(i,j) for i,v1 in enumerate(x[1:]) for j,v2 in enumerate(v1) if v2<30]

1voto

aydow Points 2342

Vous pouvez l'obtenir en utilisant zip avec

In [395]: [(a, b) for z in list(zip(x, y))[1:] for a, b in list(zip(*z)) if a >= 30]
Out[395]:
[(175, 55),
 (150, 243),
 (175, 334),
 (150, 656),
 (175, 145),
 (192, 12),
 (150, 150),
 (177, 177)]

C'est l'équivalent de

In [396]: v = []

In [398]: for z in list(zip(x, y))[1:]:
     ...:     for a, b in list(zip(*z)):
     ...:         if a >= 30:
     ...:             v.append((a,b))
     ...:

In [388]:  list(zip(x, y))[1:]
Out[388]:
[([1, 15, 175, 20], [12, 43, 55, 231]),
 ([150, 175, 18, 20], [243, 334, 44, 12]),
 ([150, 175, 18], [656, 145, 138]),
 ([192, 150, 177], [12, 150, 177])]

y

In [392]: list(zip(*list(zip(x, y))[1]))
Out[392]: [(1, 12), (15, 43), (175, 55), (20, 231)]

1voto

Mad Physicist Points 3218

Pour obtenir le corrigé y valeurs, je recommanderais de contourner entièrement les coordonnées comme première approche. La raison en est que vous risquez de vous retrouver avec des listes vides en cours de route, ce qui faussera la forme du résultat si vous n'en gardez pas une trace particulière. De plus, la suppression d'éléments est généralement beaucoup plus délicate que de ne pas les inclure en premier lieu.

Il serait beaucoup plus facile de faire une version corrigée de y de la même manière que vous avez corrigé x :

y_corr = [[n for m, n in zip(row_x, row_y) if m >= 30] for row_x, row_y in zip(x, y)]

Ici, nous avons juste utilisé zip de suivre les deux séries de listes de la même manière que vous l'avez fait avec l'une d'entre elles.

Si vous tenez absolument à utiliser les coordonnées, je vous recommande de copier simplement y entièrement et en retirant les éléments de la copie corrigée. Vous devez revenir en arrière dans chaque ligne pour éviter de modifier le sens des coordonnées (par exemple avec reversed ). Vous pouvez utiliser itertools.groupby pour effectuer l'itération réelle pour chaque ligne :

y_corr = [row.copy() for row in y]
for r, group in groupby(reversed(coord), itemgetter(0)):
    for c in map(itemgetter(1), group):
        del y_corr[r][c]

Au lieu d'inverser coord vous pouvez inverser chaque groupe individuellement, par exemple avec map(itemgetter(1), reversed(group)) .

Une meilleure approche pourrait consister à calculer les coordonnées des valeurs retenues plutôt que celles des valeurs rejetées. Je recommanderais de pré-allouer la liste de sortie, pour aider à garder la trace des listes vides et préserver la forme :

from itertools import groupby
from operator import itemgetter

coord = [(r, c) for r, row in enumerate(x) for c, n in enumerate(row) if n >= 30]

y_corr = [[]] * len(x)
for r, group in groupby(coord, itemgetter(0)):
    y_corr[r] = [y[r][c] for c in map(itemgetter(1), group)]

Si vous ne vous souciez pas de préserver les lignes vides, vous pouvez sauter la boucle et utiliser une seule ligne à la place :

y_corr = [[y[r][c] for c in map(itemgetter(1), group)] for r, group in groupby(coord, itemgetter(0))]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X