Jak usunąć ostatni wiersz danych z ramki danych pandy


119

Myślę, że to powinno być proste, ale wypróbowałem kilka pomysłów i żaden z nich nie zadziałał:

last_row = len(DF)
DF = DF.drop(DF.index[last_row])  #<-- fail!

Próbowałem używać wskaźników ujemnych, ale to również prowadziło do błędów. Nadal nie rozumiem czegoś podstawowego.


30
DF = DF[:-1]?
U2EF1

@ U2EF1 to kopiuje cały zestaw danych, prawda? Podczas obsługi ogromnych danych może to stanowić problem.
ManuelSchneid3r

Odpowiedzi:


176

Aby upuścić ostatnie n wierszy:

df.drop(df.tail(n).index,inplace=True) # drop last n rows

W tym samym duchu możesz upuścić pierwsze n wierszy:

df.drop(df.head(n).index,inplace=True) # drop first n rows

Aby upuścić ostatnią kolumnę możesz użyć df.drop (df.columns [-1], axis = 1, inplace = True) lub, jeśli znasz nazwę kolumny, możesz użyć df.drop (columns = ['nazwa_kolumny '], inplace = True) - jeśli nie chcesz, aby była wykonywana w miejscu, przypisz ją do nowej zmiennej i usuń ten argument.
Shawn Schreier


60

Ponieważ pozycjonowanie indeksu w Pythonie jest oparte na 0, w rzeczywistości nie będzie elementu w indexlokalizacji odpowiadającej len(DF). Potrzebujesz tego last_row = len(DF) - 1:

In [49]: dfrm
Out[49]: 
          A         B         C
0  0.120064  0.785538  0.465853
1  0.431655  0.436866  0.640136
2  0.445904  0.311565  0.934073
3  0.981609  0.695210  0.911697
4  0.008632  0.629269  0.226454
5  0.577577  0.467475  0.510031
6  0.580909  0.232846  0.271254
7  0.696596  0.362825  0.556433
8  0.738912  0.932779  0.029723
9  0.834706  0.002989  0.333436

[10 rows x 3 columns]

In [50]: dfrm.drop(dfrm.index[len(dfrm)-1])
Out[50]: 
          A         B         C
0  0.120064  0.785538  0.465853
1  0.431655  0.436866  0.640136
2  0.445904  0.311565  0.934073
3  0.981609  0.695210  0.911697
4  0.008632  0.629269  0.226454
5  0.577577  0.467475  0.510031
6  0.580909  0.232846  0.271254
7  0.696596  0.362825  0.556433
8  0.738912  0.932779  0.029723

[9 rows x 3 columns]

Jednak o wiele łatwiej jest po prostu pisać DF[:-1].


2
Zauważ, że podczas usuwania przy użyciu dfrm.index, indeks ostatniego wiersza powinien być unikalny, w przeciwnym razie wszystkie wiersze z tym indeksem zostaną usunięte.
FranciscoD

Czy dobrze rozumiem, że używając drop (inplace = True) modyfikujesz istniejący df, używając df [: - 1] otrzymujesz widok danych, który później może prowadzić do SettingWithCopyWarning?
Filip

29

Zaskoczony, nikt nie podniósł tego:

# To remove last n rows
df.head(-n)

# To remove first n rows
df.tail(-n)

Przeprowadzenie testu szybkości w ramce DataFrame zawierającej 1000 wierszy pokazuje, że krojenie i head/ tailsą ~ 6 razy szybsze niż użycie drop:

>>> %timeit df[:-1]
125 µs ± 132 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

>>> %timeit df.head(-1)
129 µs ± 1.18 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

>>> %timeit df.drop(df.tail(1).index)
751 µs ± 20.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Może różnica między oba podejścia jest to, że head()i tail()utworzyć widok podczas gdy drop()faktycznie zmienia reprezentację w pamięci (albo modyfikację inplace, lub tworzy zupełnie nową dataframe). Nie szukałem tego w dokumentach, ktoś proszę. (jeśli to jest różnica: dobre wyjaśnienie perf diff i trzeba dokładnie wybierać między nimi) /
Dr Jan-Philip Gehrcke

@ Dr.Jan-PhilipGehrcke Head head, taili dropwszystkie zwracają widok, chociaż to prawda, że dropdaje możliwość zmodyfikowania oryginalnej ramki danych w miejscu.
theGirrafish

5
stats = pd.read_csv("C:\\py\\programs\\second pandas\\ex.csv")

Wynik statystyk:

       A            B          C
0   0.120064    0.785538    0.465853
1   0.431655    0.436866    0.640136
2   0.445904    0.311565    0.934073
3   0.981609    0.695210    0.911697
4   0.008632    0.629269    0.226454
5   0.577577    0.467475    0.510031
6   0.580909    0.232846    0.271254
7   0.696596    0.362825    0.556433
8   0.738912    0.932779    0.029723
9   0.834706    0.002989    0.333436

po prostu użyj skipfooter=1

skipfooter: int, domyślnie 0

Liczba linii na dole pliku do pominięcia

stats_2 = pd.read_csv("C:\\py\\programs\\second pandas\\ex.csv", skipfooter=1, engine='python')

Wyjście statystyk_2

       A          B            C
0   0.120064    0.785538    0.465853
1   0.431655    0.436866    0.640136
2   0.445904    0.311565    0.934073
3   0.981609    0.695210    0.911697
4   0.008632    0.629269    0.226454
5   0.577577    0.467475    0.510031
6   0.580909    0.232846    0.271254
7   0.696596    0.362825    0.556433
8   0.738912    0.932779    0.029723

1

drop zwraca nową tablicę, dlatego została zablokowana w poście og; Miałem podobny wymóg, aby zmienić nazwy niektórych nagłówków kolumn i usunąć niektóre wiersze z powodu źle uformowanego pliku csv przekonwertowanego na Dataframe, więc po przeczytaniu tego postu użyłem:

newList = pd.DataFrame(newList)
newList.columns = ['Area', 'Price']
print(newList)
# newList = newList.drop(0)
# newList = newList.drop(len(newList))
newList = newList[1:-1]
print(newList)

i działało świetnie, jak widać z dwoma zakomentowanymi wierszami powyżej, wypróbowałem metodę drop. () i działa, ale nie jest tak fajna i czytelna jak użycie [n: -n], mam nadzieję, że komuś pomoże, dzięki.


0

W przypadku bardziej złożonych ramek DataFrame, które mają Multi-indeks (powiedz „Giełda” i „Data”) i chcesz usunąć ostatni wiersz dla każdego Akcji, a nie tylko ostatni wiersz ostatniego Akcji, wówczas rozwiązanie brzmi:

# To remove last n rows
df = df.groupby(level='Stock').apply(lambda x: x.head(-1)).reset_index(0, drop=True)

# To remove first n rows
df = df.groupby(level='Stock').apply(lambda x: x.tail(-1)).reset_index(0, drop=True)

Ponieważ groupby()dodaje dodatkowy poziom do Multi-Index, po prostu upuszczamy go na końcu za pomocą reset_index(). Wynikowy plik df zachowuje ten sam typ multi-indeksu, co przed operacją.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.