Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to shift several rows in a pandas DataFrame?

I have the following pandas Dataframe:

import pandas as pd
data = {'one' : pd.Series([1.], index=['a']), 'two' : pd.Series([1., 2.], index=['a', 'b']), 'three' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(data)
df = df[["one", "two", "three"]]


   one  two  three
a  1.0  1.0    1.0
b  NaN  2.0    2.0
c  NaN  NaN    3.0
d  NaN  NaN    4.0

I know how to shift elements by column upwards/downwards, e.g.

df.two = df.two.shift(-1)

   one  two  three
a  1.0  2.0    1.0
b  NaN  NaN    2.0
c  NaN  NaN    3.0
d  NaN  NaN    4.0

However, I would like to shift all elements in row a over two columns and all elements in row b over one column. The final data frame would look like this:

   one  two  three
a  NaN  NaN    1.0
b  NaN  NaN    2.0
c  NaN  NaN    3.0
d  NaN  NaN    4.0

How does one do this in pandas?

like image 519
ShanZhengYang Avatar asked Mar 11 '17 07:03

ShanZhengYang


People also ask

How do I move rows in pandas DataFrame?

shift() If you want to shift your column or subtract the column value with the previous row value from the DataFrame, you can do it by using the shift() function. It consists of a scalar parameter called period, which is responsible for showing the number of shifts to be made over the desired axis.

How do I replace multiple rows in pandas?

Pandas replace multiple values in column replace. By using DataFrame. replace() method we will replace multiple values with multiple new strings or text for an individual DataFrame column. This method searches the entire Pandas DataFrame and replaces every specified value.

How do I drop multiple rows in a DataFrame?

Delete a Multiple Rows by Index Position in DataFrame As df. drop() function accepts only list of index label names only, so to delete the rows by position we need to create a list of index names from positions and then pass it to drop(). As default value of inPlace is false, so contents of dfObj will not be modified.


Video Answer


2 Answers

IMHO, this is a more pythonic way:

df.loc['a'] = df.loc['a'].shift(periods=2,axis=0)

Note in this case .loc returns a Series, so axis=0 is optional.

like image 59
marcio Avatar answered Oct 15 '22 04:10

marcio


You can transpose the initial DF so that you have a way to access the row labels as column names inorder to perform the shift operation.

Shift the contents of the respective columns downward by those amounts and re-transpose it back to get the desired result.

df_t = df.T
df_t.assign(a=df_t['a'].shift(2), b=df_t['b'].shift(1)).T

enter image description here

like image 35
Nickil Maveli Avatar answered Oct 15 '22 02:10

Nickil Maveli