254

I think this should be simple, but I tried a few ideas and none of them worked:

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

I tried using negative indices but that also lead to errors. I must still be misunderstanding something basic.

6
  • 48
    DF = DF[:-1]? Commented Nov 14, 2014 at 1:55
  • @U2EF1 this copies the entire dataset, doesnt it? When handling huge data this may be an issue. Commented Dec 17, 2019 at 18:50
  • if last_row is taking the length of DF, then you need to use (last_row-1) for indexing. Commented Jul 17, 2021 at 18:31
  • 2
    It's good practice to use df.shape[0] rather than len(df) to get the number of rows. Commented Aug 12, 2021 at 14:27
  • 1
    Why is that good practice @pabz? Commented Jun 6, 2022 at 22:22

11 Answers 11

343

To drop last n rows:

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

By the same vein, you can drop first n rows:

df.drop(df.head(n).index,inplace=True) # drop first n rows
Sign up to request clarification or add additional context in comments.

2 Comments

To drop the last column you can use df.drop(df.columns[-1], axis=1, inplace=True) or, if you know the name of the column you can use df.drop(columns=['col_name'], inplace=True) - if you do not want it to be performed in place, assign it to a new variable and remove that argument.
This method only works if the index of the last row is unique, as it removes all the rows that have the same index as the last n rows. @blue-sky 's answer seems more appropriate
223
DF[:-n]

where n is the last number of rows to drop.

To drop the last row :

DF = DF[:-1]

4 Comments

This works, but I suspect Wes McKinney wouldn't like it. Why not use the stuff built into Pandas?
Maybe deprecated because I got an error, it was looking for a column named -1. Had to use df = df.iloc[:-1]
According to my tests, this is at least 6 times faster than using .drop()!
Does this create a view or a copy? Possibly explains the speed difference if it's a view.
66

Surprised nobody brought this one up:

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

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

Running a speed test on a DataFrame of 1000 rows shows that slicing and head/tail are ~6 times faster than using 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)

2 Comments

Maybe the difference between both approaches is that head() and tail() create a view whereas drop() actually changes representation in memory (either inplace modification, or creates an entirely new dataframe). I did not look this up in docs, someone please do. (if that's the difference: good explanation for perf diff, and one needs to carefully choose between them)/
@Dr.Jan-PhilipGehrcke Head head, tail and drop all return a view, although it's true that drop gives you the option to modify the original dataframe inplace.
64

Since index positioning in Python is 0-based, there won't actually be an element in index at the location corresponding to len(DF). You need that to be 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]

However, it's much simpler to just write DF[:-1].

2 Comments

Note that when dropping using dfrm.index, the index of the last row should be unique, otherwise all rows with that index are dropped.
Do I understand correctly, that using drop (inplace=True) you modifiy the existing df, while using df[:-1] you get a view of data, which later can lead to SettingWithCopyWarning?
22

The nicest solution I've found that doesn't (necessarily?) do a fully copy is

df.drop(df.index[-1], inplace=True)

Of course, you can simply omit inplace=True to create a new dataframe, and you can also easily delete the last N rows by simply taking slices of df.index (df.index[-N:] to drop the last N rows). So this approach is not only concise but also very flexible.

Comments

18

Just use indexing

df.iloc[:-1,:]

That's why iloc exists. You can also use head or tail.

1 Comment

Consider expanding on your answer and explaining how and why your solution works
8
stats = pd.read_csv("C:\\py\\programs\\second pandas\\ex.csv")

The Output of stats:

       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

just use skipfooter=1

skipfooter : int, default 0

Number of lines at bottom of file to skip

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

Output of stats_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

Comments

2

you know what, you just need to gave -1 in first line, like this

last_row = len(DF) - 1
DF = DF.drop(DF.index[last_row])

Comments

1

For more complex DataFrames that have a Multi-Index (say "Stock" and "Date") and one wants to remove the last row for each Stock not just the last row of the last Stock, then the solution reads:

# 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)

As the groupby() is adding an additional level to the Multi-Index we just drop it at the end using reset_index(). The resulting df keeps the same type of Multi-Index as before the operation.

Comments

0

drop returns a new array so that is why it choked in the og post; I had a similar requirement to rename some column headers and deleted some rows due to an ill formed csv file converted to Dataframe, so after reading this post I used:

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)

and it worked great, as you can see with the two commented out lines above I tried the drop.() method and it work but not as kool and readable as using [n:-n], hope that helps someone, thanks.

1 Comment

It's exactly the same as many other answers already present.
0

DF.drop((labels=None, axis=0, index = last_row)

as a function of:

DataFrame.drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors='raise')

Drop specified labels from rows or columns.

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.drop.html

1 Comment

Your answer could be improved with some formatting, see also Markdown help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.