Skip to content Skip to sidebar Skip to footer

Shifting Values To The Top In A Python Dataframe If Nan Values Are Encountered

I am working with an irregular df. I am trying to get rid of the initial NaNs and shift all values to the top leaving NaNs at the bottom. I want to perform a realignment of the val

Solution 1:

You iterate over the cols and using first_valid_index and get_loc shift the col values:

In [314]:
for col in df:
    df[col] = df[col].shift(-df.index.get_loc(df[col].first_valid_index()))
df

Out[314]:
            col1  col2  col3  col4  col5  col6  col7  col8
STRIP                                                     
01/12/2011   0.8   0.8  0.78   0.7   0.6   0.6   0.1   0.7
01/01/2012   0.8   0.8  0.75   0.7   0.6   0.6   0.2   0.9
01/02/2012   0.8   0.8  0.73   0.7   0.6   0.6   0.3   0.6
01/03/2012   0.8   0.7  0.72   0.7   0.6   0.6   0.4   0.4
01/04/2012   0.7   0.7  0.70   0.7   0.6   0.6   0.5   0.3
01/05/2012   0.7   0.7  0.69   0.7   0.6   0.6   0.8   0.2
01/06/2012   0.7   0.7  0.68   0.7   0.6   0.6   0.7   NaN
01/07/2012   0.7   0.7  0.67   NaN   0.5   0.6   NaN   NaN
01/08/2012   0.7   0.7   NaN   NaN   0.5   NaN   NaN   NaN
01/09/2012   0.7   NaN   NaN   NaN   NaN   NaN   NaN   NaN
02/01/2013   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
03/01/2013   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN

Another method using apply:

In [317]:
df.apply(lambda x: x.shift(-x.index.get_loc(x.first_valid_index())))

Out[317]:
            col1  col2  col3  col4  col5  col6  col7  col8
STRIP                                                     
01/12/2011   0.8   0.8  0.78   0.7   0.6   0.6   0.1   0.7
01/01/2012   0.8   0.8  0.75   0.7   0.6   0.6   0.2   0.9
01/02/2012   0.8   0.8  0.73   0.7   0.6   0.6   0.3   0.6
01/03/2012   0.8   0.7  0.72   0.7   0.6   0.6   0.4   0.4
01/04/2012   0.7   0.7  0.70   0.7   0.6   0.6   0.5   0.3
01/05/2012   0.7   0.7  0.69   0.7   0.6   0.6   0.8   0.2
01/06/2012   0.7   0.7  0.68   0.7   0.6   0.6   0.7   NaN
01/07/2012   0.7   0.7  0.67   NaN   0.5   0.6   NaN   NaN
01/08/2012   0.7   0.7   NaN   NaN   0.5   NaN   NaN   NaN
01/09/2012   0.7   NaN   NaN   NaN   NaN   NaN   NaN   NaN
02/01/2013   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
03/01/2013   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN

EDIT

If 'STRIP' is a column then you don't need get_loc:

In [319]:
df.apply(lambda x: x.shift(-x.first_valid_index()))

Out[319]:
         STRIP  col1  col2  col3  col4  col5  col6  col7  col8
0   01/12/2011   0.8   0.8  0.78   0.7   0.6   0.6   0.1   0.7
1   01/01/2012   0.8   0.8  0.75   0.7   0.6   0.6   0.2   0.9
2   01/02/2012   0.8   0.8  0.73   0.7   0.6   0.6   0.3   0.6
3   01/03/2012   0.8   0.7  0.72   0.7   0.6   0.6   0.4   0.4
4   01/04/2012   0.7   0.7  0.70   0.7   0.6   0.6   0.5   0.3
5   01/05/2012   0.7   0.7  0.69   0.7   0.6   0.6   0.8   0.2
6   01/06/2012   0.7   0.7  0.68   0.7   0.6   0.6   0.7   NaN
7   01/07/2012   0.7   0.7  0.67   NaN   0.5   0.6   NaN   NaN
8   01/08/2012   0.7   0.7   NaN   NaN   0.5   NaN   NaN   NaN
9   01/09/2012   0.7   NaN   NaN   NaN   NaN   NaN   NaN   NaN
10  02/01/2013   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
11  03/01/2013   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN

Solution 2:

I think you can just stack the valid numbers and nan's back together:

In [95]:

df2 = df.apply(lambda x: np.hstack((x[~x.isnull()], x[x.isnull()])), axis=0)
print df2

         STRIP  col1  col2  col3  col4  col5  col6  col7  col8
0   01/12/2011   0.8   0.8  0.78   0.7   0.6   0.6   0.1   0.7
1   01/01/2012   0.8   0.8  0.75   0.7   0.6   0.6   0.2   0.9
2   01/02/2012   0.8   0.8  0.73   0.7   0.6   0.6   0.3   0.6
3   01/03/2012   0.8   0.7  0.72   0.7   0.6   0.6   0.4   0.4
4   01/04/2012   0.7   0.7  0.70   0.7   0.6   0.6   0.5   0.3
5   01/05/2012   0.7   0.7  0.69   0.7   0.6   0.6   0.8   0.2
6   01/06/2012   0.7   0.7  0.68   0.7   0.6   0.6   0.7   NaN
7   01/07/2012   0.7   0.7  0.67   NaN   0.5   0.6   NaN   NaN
8   01/08/2012   0.7   0.7   NaN   NaN   0.5   NaN   NaN   NaN
9   01/09/2012   0.7   NaN   NaN   NaN   NaN   NaN   NaN   NaN
10  02/01/2013   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN
11  03/01/2013   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN

Post a Comment for "Shifting Values To The Top In A Python Dataframe If Nan Values Are Encountered"