Seite 1 von 1

Nan aus der Liste entfernen

Verfasst: Montag 16. September 2013, 09:44
von mickimick
Hey,
ich habe eine Liste mit ein paar nan- Einträgen, also

Code: Alles auswählen

L=[1,nan,12,5,324,nan,93]
,
und zudem eine Liste die fünfmal so lang ist wie L, also

Code: Alles auswählen

T=[1,2,1,2,3,4,5,33,42,435,643,234,123,643,234,123,52,6,4,43,634,3234,35,12,786,43,754,85,35,6,4,2,1,6,53]
.
Wie ich die nan Einträge effizient aus der ersten Liste entferne ist mir klar.

Code: Alles auswählen

L=L[isnan(L)==False]
Jetzt möchte ich genauso effektiv die fünf Elemente aus T entfernen, die zu meinen nan aus der ersten Liste gehören. Also, wenn in der ersten Liste mein nan an Stelle 1 steht, möchte ich die Elemente 5-9 aus meiner Liste T entfernen.
Wie kann ich das effektiv machen??
Danke für eure Hilfe!

Re: Nan aus der Liste entfernen

Verfasst: Montag 16. September 2013, 10:16
von sparrow
Keine Ahnung ob man das als LC zusammenfassen kann, aber ich würde mir überlegen, ob die Abbildung als zwei Listen für die Daten tatsächlich richtig ist. Ich würde ein dict machen, wobei der Schlüssel der Wert aus L ist und als Wert die Daten aus T, die dazu passen. Dann hätte man in den Daten auch gleich den entsprechenden Zusammenhang.

Was immer geht ist die Möglichkeit die Daten entsprechend Stück für Stück zu prüfen und dann die Listen zu bearbeiten:

Code: Alles auswählen

>>> L=[1,"nan",12,5,324,"nan",93]
>>> T=[1,2,1,2,3,4,5,33,42,435,643,234,123,643,234,123,52,6,4,43,634,3234,35,12,786,43,754,85,35,6,4,2,1,6,53]
>>> removes=[]
>>> for i, val in enumerate(L):
	if val == "nan":
		removes += range(i*5, i*5+5)

		
>>> for remove in removes[::-1]:
	del T[remove]

	
>>> T
[1, 2, 1, 2, 3, 643, 234, 123, 643, 234, 123, 52, 6, 4, 43, 634, 3234, 35, 12, 786, 4, 2, 1, 6, 53]

Re: Nan aus der Liste entfernen

Verfasst: Montag 16. September 2013, 10:17
von mutetella
Hallo,

falls ich Dich richtig verstehe:

Code: Alles auswählen

>>> L = [1, 'nan', 12, 5, 324, 'nan', 93]
>>> T = [1, 2, 1, 2, 3, 4, 5, 33 ,42, 435 , 643, 234, 123, 643, 234, 123, 52, 6, 4, 43, 634, 3234, 35, 12, 786, 43, 754, 85, 35, 6, 4, 2, 1, 6, 53]
>>> index2remove = [index for index, elem in enumerate(L) if elem == 'nan']
>>> new_T = [t for index, t in enumerate(T) if index not in range(index2remove[0], index2remove[1] + 1)]
Falls `L` mehrere `nan` enthält, kannst Du ja statt der `new_T` LC eine Schleife machen...

mutetella

Re: Nan aus der Liste entfernen

Verfasst: Montag 16. September 2013, 10:46
von Hyperion
mickimick hat geschrieben: Jetzt möchte ich genauso effektiv die fünf Elemente aus T entfernen, die zu meinen nan aus der ersten Liste gehören.
Ich sehe hier in XY-Problem! Wieso sind das getrennte Strukturen (also *zwei* Listen), wenn die Daten zueinander in Beziehung stehen? Sinnvoller könnte es sein, die Daten von vornherein zusammen zu fassen. Dazu benötigen wir aber mehr Kontext.

Re: Nan aus der Liste entfernen

Verfasst: Montag 16. September 2013, 12:19
von jerch
mickimick hat geschrieben:Wie ich die nan Einträge effizient aus der ersten Liste entferne ist mir klar.
Code:
L=L[isnan(L)==False]
Nein ist es nicht. Dein Code tut nicht was Du erwartest und liefert einen Fehler (falls L die Liste von oben ist), was man übringens mit der interaktiven Shell sehr schnell selbst rausfinden kann ;)

Code: Alles auswählen

>>> from math import isnan
>>> nan=float('nan')
>>> L=[1,nan,12,5,324,nan,93]
>>> filter(lambda x: not isnan(x), L)
[1, 12, 5, 324, 93]
Zu dem anderen Problem, soweit ich es verstanden habe:

Code: Alles auswählen

>>> T=[1,2,1,2,3,4,5,33,42,435,643,234,123,643,234,123,52,6,4,43,634,3234,35,12,786,43,754,85,35,6,4,2,1,6,53]
>>> [v for i,v in enumerate(T) if not isnan(L[i/5])]
[1, 2, 1, 2, 3, 643, 234, 123, 643, 234, 123, 52, 6, 4, 43, 634, 3234, 35, 12, 786, 4, 2, 1, 6, 53]

Re: Nan aus der Liste entfernen

Verfasst: Montag 16. September 2013, 12:31
von BlackJack
@mickimick: Wenn Du die `nan`-Werte wie gezeigt aus `L` entfernen kannst, dann ist `L` schon mal keine Liste sondern sehr wahrscheinlich ein Numpy-Array. Dann sieht die Darstellung aber auch nicht *so* aus, denn `nan` kann nur in Arrays mit Gleitkommazahlen vorkommen. Was auch schön gewesen wäre wenn die Länge der Arrays der beschreibung im Text entspräche, denn `T` ist in dem Beispiel gar nicht 5 mal so lang wie `L`.

Du weisst ja offensichtlich wie man einen Index für `L` erstellt. Obwohl das noch etwas kürzer ginge, denn statt die Elemente mit `False` zu vergleichen um sie zu negieren kann man auch den ``~``-Operator verwenden: ``~isnan(L)``. Ich gehe jetzt mal davon aus, dass `T` auch ein Array ist und keine Liste. Dann kann man dort doch einfach die Form in ein 2D-Array ändern, den gleichen Index wie für `L` verwenden und das Ergebnis wieder „flach klopfen”. Wobei sich hier auch die Frage stellt warum das eine eindimensionale Struktur ist wenn jeweils fünf aufeinanderfolgende Werte mit einem Wert aus `L` korrespondieren. Das ist umständlich und führt genau zu solchen Fragen wie in diesem Beitrag.

Also mal Schritt für Schritt entwickelt:

Code: Alles auswählen

In [24]: L
Out[24]: array([   1.,   nan,   12.,    5.,  324.,   nan])

In [25]: T
Out[25]: 
array([   1,    2,    1,    2,    3,    4,    5,   33,   42,  435,  643,
        234,  123,  643,  234,  123,   52,    6,    4,   43,  634, 3234,
         35,   12,  786,   43,  754,   85,   35,    6,    4,    2,    1,
          6,   53])

In [26]: idx = ~np.isnan(L)

In [27]: L[idx]
Out[27]: array([   1.,   12.,    5.,  324.])

In [28]: T.reshape((5, None))
Out[28]: 
array([[   1,    2,    1,    2,    3,    4,    5],
       [  33,   42,  435,  643,  234,  123,  643],
       [ 234,  123,   52,    6,    4,   43,  634],
       [3234,   35,   12,  786,   43,  754,   85],
       [  35,    6,    4,    2,    1,    6,   53]])

In [29]: T.reshape((5, None))[idx]
Out[29]: 
array([[   1,    2,    1,    2,    3,    4,    5],
       [ 234,  123,   52,    6,    4,   43,  634],
       [3234,   35,   12,  786,   43,  754,   85],
       [  35,    6,    4,    2,    1,    6,   53]])

In [30]: T.reshape((5, None))[idx].flatten()
Out[30]: 
array([   1,    2,    1,    2,    3,    4,    5,  234,  123,   52,    6,
          4,   43,  634, 3234,   35,   12,  786,   43,  754,   85,   35,
          6,    4,    2,    1,    6,   53])