Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move given row to end of DataFrame

I would like to take a given row from a DataFrame and prepend or append to the same DataFrame.

My code below does just that, but I'm not sure if I'm doing it the right way or if there is an easier, better, faster way?

testdf = df.copy()
#get row 
target_row = testdf.ix[[2],:]
#del row from df
testdf.drop([testdf.index[2]], axis=0, inplace=True)
#concat original row to end or start of df
newdf = pd.concat([testdf, target_row], axis=0)

Thanks

like image 693
Boosted_d16 Avatar asked Jun 19 '15 14:06

Boosted_d16


People also ask

How do I move a row to the top of a Pandas Dataframe?

Solution 1: using list and pd.concat([], ignore_index=True) to add it at the top (at index 0) of dataframe.

How do I change the position of a row in pandas?

To move the third row to the first, you can create an index moving the target row to the first element. I use a conditional list comprehension to join by lists. Then, just use iloc to select the desired index rows. Save this answer.

How do I get back to the last row in pandas?

Select & print last row of dataframe using tail() It will return the last row of dataframe as a dataframe object. Using the tail() function, we fetched the last row of dataframe as a dataframe and then just printed it.

How do I drop the last 10 rows in a Dataframe?

We can remove the last n rows using the drop() method. drop() method gets an inplace argument which takes a boolean value. If inplace attribute is set to True then the dataframe gets updated with the new value of dataframe (dataframe with last n rows removed).


2 Answers

Rather than concat I would just assign directly to the df after shifting, then use iloc to reference the position you want to assign the row, you have to call squeeze so that you assign just the values and lose the original index value otherwise it'll raise a ValueError:

In [210]:
df = pd.DataFrame({'a':np.arange(5)})
df

Out[210]:
   a
0  0
1  1
2  2
3  3
4  4

In [206]:
target_row = df.ix[[2],:]
target_row

Out[206]:
   a
2  2

In [211]:
df = df.shift()
df.iloc[0] = target_row.squeeze()
df

Out[211]:
   a
0  2
1  0
2  1
3  2
4  3

EDIT

To insert at the end:

In [255]:
df = pd.DataFrame({'a':np.arange(5)})
target_row = df.ix[[2],:]
df = df.shift(-1)
df.iloc[-1] = target_row.squeeze()
df

Out[255]:
   a
0  1
1  2
2  3
3  4
4  2

Another update

Thanks to @AsheKetchum for pointing out that my earlier answer is incorrect, now looking at this 3 years later I realise you could just reindex the orig df:

If we take a copy of the index as a list:

In[24]:
idx = df.index.tolist()
idx

Out[24]: [0, 1, 2, 3, 4]

then we can pop the index of interest from this list:

In[25]:
idx.pop(2)
idx

Out[25]: [0, 1, 3, 4]

Now we can reindex by prepending to this list:

In[26]:
df.reindex([2] + idx)

Out[26]: 
   a
2  2
0  0
1  1
3  3
4  4

Or appending:

In[27]:    
df.reindex(idx+[2])

Out[27]: 
   a
0  0
1  1
3  3
4  4
2  2
like image 134
EdChum Avatar answered Nov 02 '22 12:11

EdChum


To improve performance, you may want to consider keeping a running list of all rows you want to move to the end of the DataFrame, and then move them all at once in a single pd.concat operation.

df = pd.DataFrame(np.random.rand(5, 3), columns=list('ABC'))
target_rows = [1, 3, 4]

a = df.iloc[[i for i in df.index if i not in target_rows], :]
b = df.iloc[target_rows, :]
>>> pd.concat([a, b])
          A         B         C
0  0.818722  0.174153  0.522383
2  0.581577  0.840306  0.985089
1  0.645752  0.238476  0.670922
3  0.198271  0.501911  0.954477
4  0.965488  0.735559  0.701077
like image 31
Alexander Avatar answered Nov 02 '22 13:11

Alexander