Reputation: 31
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 value at the top which ignores the date.
==================================================================
STRIP col1 col2 col3 col4 col5 col6 col7 col8
01/12/2011 0.8 NaN NaN NaN NaN NaN NaN NaN
01/01/2012 0.8 0.8 NaN NaN NaN NaN NaN NaN
01/02/2012 0.8 0.8 0.78 NaN NaN NaN NaN NaN
01/03/2012 0.8 0.8 0.75 0.7 0.6 NaN NaN NaN
01/04/2012 0.7 0.7 0.73 0.7 0.6 0.6 NaN NaN
01/05/2012 0.7 0.7 0.72 0.7 0.6 0.6 0.1 NaN
01/06/2012 0.7 0.7 0.70 0.7 0.6 0.6 0.2 0.7
01/07/2012 0.7 0.7 0.69 0.7 0.6 0.6 0.3 0.9
01/08/2012 0.7 0.7 0.68 0.7 0.6 0.6 0.4 0.6
01/09/2012 0.7 0.7 0.67 0.7 0.6 0.6 0.5 0.4
02/01/2013 NaN NaN NaN NaN 0.5 0.6 0.8 0.3
03/01/2013 NaN NaN NaN NaN 0.5 0.6 0.7 0.2
===================================================================
the final DataFrame should look like the following:
STRIP col1 col2 col3 col4 col5 col6 col7 col8
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.7 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.6 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
Upvotes: 3
Views: 93
Reputation: 54340
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
Upvotes: 1
Reputation: 394099
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
Upvotes: 1