2016-08-19 16 views
5

Jestem trochę zirytowany sobą, ponieważ nie mogę zrozumieć, dlaczego jedno rozwiązanie problemu zadziałało, a inne nie. Tak jak w przypadku, wskazuje to na niedostateczne zrozumienie (podstawowych) pand z mojej strony, a to doprowadza mnie do szału!Sprawdzanie listy działa, ale nie dla pętli - dlaczego?

W każdym razie mój problem był prosty: miałem listę "złych" wartości ("bad_index"); odpowiadały one indeksom wierszy na ramie danych ("data_clean1"), dla których chciałem usunąć odpowiednie wiersze. Jednak ponieważ wartości zmieniają się z każdym nowym zestawem danych, nie chcę podłączać złych wartości bezpośrednio do kodu. Oto co zrobiłem najpierw:

bad_index = [2, 7, 8, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 29] 

for i in bad_index: 
    dataclean2 = dataclean1.drop([i]).reset_index(level = 0, drop = True) 

Ale to nie zadziałało; data_clean2 pozostała taka sama jak data_clean1. Moim drugim pomysłem było użycie wyrażeń listowych (jak poniżej); to działało dobrze.

bad_index = [2, 7, 8, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 29] 

data_clean2 = data_clean1.drop([x for x in bad_index]).reset_index(level = 0, drop = True) 

Dlaczego teraz działa metoda sprawdzania listy, a nie pętla "za"? Kodowałem od kilku miesięcy i uważam, że nie powinienem popełniać tego rodzaju błędów.

Dzięki!

+0

Nie jestem pewien, co robi 'drop', ale wiem, że w' pętli for 'zmieniasz 'dataclean2' podczas każdej iteracji. –

+0

Czy chodzi ci o rozumienie list, a nie wyrażenie regularne? Jeśli chodzi o popełnianie błędów, koduję od lat i nadal napotykam na problemy, których nie rozumiem, i popełniam błędy, które moim zdaniem nie powinny! Chciałbym móc powiedzieć, że błędy znikają z upływem czasu ... – johnchase

+0

Tak, zredagowano dla jasności! – Lodore66

Odpowiedz

8

data_clean1.drop([x for x in bad_index]).reset_index(level = 0, drop = True) jest odpowiednikiem zwykłego podanialista do drop:

data_clean1.drop(bad_index).reset_index(level = 0, drop = True)

drop przyjmuje listę i spada każdy indeks obecny na liście.

wyraźnej for pętla nie działa, ponieważ w każdej iteracji po prostu spadł inny indeks z dataclean1 dataframe bez zapisywania pośrednich dataframes, więc przez ostatni iteracji dataclean2 było po prostu wynikiem wykonywania
dataclean2 = dataclean1.drop(29).reset_index(level = 0, drop = True)

+0

o człowieku, to co dostaję za nie przeczytanie pytania w całości +1 dobra odpowiedź –

+1

Świetna odpowiedź - dzięki! To wyjaśnia to bardzo ładnie. Zabawne jest to, że nigdy nie popełniłbym tego błędu powtarzając listę. Ale przynajmniej nie powtórzę tego ... – Lodore66

1

EDIT: Okazuje się, to nie jest problem ... ale jeśli nie masz problemu, o którym mowa w drugim Odpowiedź Deepspace wtedy masz ten problem

for i in bad_index: 
    dataclean2 = dataclean1.drop([i]).reset_index(level = 0, drop = True) 

wyobrazić sobie zły indeks jest [1,2,3] a dataclean jest [4,5,6,7,8]

teraz pozwala krok po kroku, co faktycznie dzieje się

początkowa: dataclean == [4,5,6,7,8]

loop0: i == 1 => Indeks spadek 1 ==> dataclean = [4,6,7,8]

loop1: i == 2 => spadek indeksu 2 ==> dataclean = [4,6,8]

loop2: i == 3 ==> spadek indeksu 3 !!!! uh oh nie ma indeksu 3


można chyba zrobić zamiast

for i in reversed(bad_index): 
    ... 

ten sposób, jeśli usunąć index3 pierwszy nie wpłynie to indeks 1 i 2

ale w ogóle nie powinieneś mutować listy/dyktatu podczas iteracji

+0

Bez obaw - i dobra rada niezależnie! – Lodore66

Powiązane problemy