thisisforwork
thisisforwork

Reputation: 37

How to stack two columns of a pandas dataframe in python

I want to stack two columns on top of each other

So I have Left and Right values in one column each, and want to combine them into a single one. How do I do this in Python? I'm working with Pandas Dataframes.

Basically from this

  Left Right
0  20   25
1  15   18
2  10   35
3  0     5

To this:

  New Name
0  20   
1  15   
2  10   
3  0    
4  25
5  18
6  35
7  5

It doesn't matter how they are combined as I will plot it anyway, and the new column name also doesn't matter because I can rename it.

Upvotes: 1

Views: 2810

Answers (6)

JAdel
JAdel

Reputation: 1616

A solution with masking.

# Your data
import numpy as np
import pandas as pd
df = pd.DataFrame({"Left":[20,15,10,0], "Right":[25,18,35,5]})

# Masking columns to ravel
df2 = pd.DataFrame({"New Name":np.ravel(df[["Left","Right"]])})

df2

   New Name
0        20
1        25
2        15
3        18
4        10
5        35
6         0
7         5

Upvotes: 0

thisisforwork
thisisforwork

Reputation: 37

I ended up using this solution, seems to work fine

df1 = dfTest[['Left']].copy()
df2 = dfTest[['Right']].copy()
df2.columns=['Left']
df3 = pd.concat([df1, df2],ignore_index=True)

Upvotes: -2

Klaus78
Klaus78

Reputation: 11906

Solution with unstack

df2 = df.unstack()
# recreate index
df2.index = np.arange(len(df2))

Upvotes: 1

Corralien
Corralien

Reputation: 120409

You can also use np.ravel:

import numpy as np

out = pd.DataFrame(np.ravel(df.values.T), columns=['New name'])
print(out)

# Output
   New name
0        20
1        15
2        10
3         0
4        25
5        18
6        35
7         5

Update

If you have only 2 cols:

out = pd.concat([df['Left'], df['Right']], ignore_index=True).to_frame('New name')
print(out)

# Output
   New name
0        20
1        15
2        10
3         0
4        25
5        18
6        35
7         5

Upvotes: 1

timgeb
timgeb

Reputation: 78690

Many options, stack, melt, concat, ...

Here's one:

>>> df.melt(value_name='New Name').drop('variable', 1)
   New Name
0        20
1        15
2        10
3         0
4        25
5        18
6        35
7         5

Upvotes: 3

Josip Juros
Josip Juros

Reputation: 359

You can create a list of the cols, and call squeeze to anonymise the data so it doesn't try to align on columns, and then call concat on this list, passing ignore_index=True creates a new index, otherwise you'll get the names as index values repeated:

cols = [df[col].squeeze() for col in df]
pd.concat(cols, ignore_index=True)

Upvotes: 6

Related Questions