2

I am looking for a way to convert my dataframe columns as rows. Following is my example dataframe:

mylist= [['xx'], [None, 'yy'], ['xx', None], ['xx',None],['xx','yy']]

pd.DataFrame(mylist,index=['A','B','C','D','E'],columns=['Col1','Col2'])

Input DataFrame:

-------------------
Ind | Col1 | Col2 |
-------------------
A   | xx   | None |
B   | None | yy   |
C   | xx   | None |
D   | xx   | None |
E   | xx   | yy   |
-------------------

I want to split my columns as separate rows in the dataframe. Below is how my desired output looks like. Can anyone suggest how to acheive the following.

Desired dataframe:

------------------------
Ind | Values | Columns |
------------------------
A   | xx     | Col1    |
B   | yy     | Col2    |
C   | xx     | Col1    |
D   | xx     | Col1    |
E   | xx     | Col1    |
E   | xx     | Col2    |
------------------------

Thanks,
Rtut

3 Answers 3

3

Another option is to use melt:

longDf = pd.melt(df.reset_index(), id_vars=['index'], var_name=['Columns'])
longDf[pd.notnull(longDf.value)]

  index Columns value
0   A   Col1    xx
2   C   Col1    xx
3   D   Col1    xx
4   E   Col1    xx
6   B   Col2    yy
9   E   Col2    yy
Sign up to request clarification or add additional context in comments.

1 Comment

@bernie Thanks. stack() is also a great way to do it.
2
df = pd.DataFrame(mylist,index=['A','B','C','D','E'],columns=['Col1','Col2'])
# rotate df
stacked_df = pd.DataFrame(df.stack().reset_index())
# name columns
stacked_df.columns = ['Ind','Columns','Values']
# reorder columns
reordered_df = pd.DataFrame(stacked_df,columns=['Ind','Values','Columns'])

Results in:

>>> reordered_df
  Ind Values Columns
0   A     xx    Col1
1   B     yy    Col2
2   C     xx    Col1
3   D     xx    Col1
4   E     xx    Col1
5   E     yy    Col2

Comments

1

In the case of two values, it appears that you only want the first (e.g. the last row of your example).

You can use loc to first set the second value to None in the case both columns have values.

df.loc[(df.Col1.notnull()) & (df.Col2.notnull()), 'Col2'] = None

You can then melt your results.

>>> pd.melt(df.reset_index(), id_vars='index', var_name='Columns', value_name='Values'
            ).dropna().set_index('index')[['Values', 'Columns']]

      Values Columns
index               
A         xx    Col1
C         xx    Col1
D         xx    Col1
E         xx    Col1
B         yy    Col2

Comments

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.