Suppose I have DataFrame
df
:
a b c
v f 3|4|5
v 2 6
v f 4|5
I'd like to produce this df
:
a b c
v f 3
v f 4
v f 5
v 2 6
v f 4
v f 5
I know how to make this transformation in R, using tidyr
package.
Is there an easy way of doing this in pandas?
Unnesting is nothing but exploding the lists into rows. So this transformation can be done easily with the help of the pandas series. explode() method. This method is used to transform list-like elements of a series object into rows, and the index will be duplicated for these rows.
In Pandas, there are parameters to perform left, right, inner or outer merge and join on two DataFrames or Series. However there's no possibility as of now to perform a cross join to merge or join two methods using how="cross" parameter.
Column(s) to explode. For multiple columns, specify a non-empty list with each element be str or tuple, and all specified columns their list-like data on same row of the frame must have matching length. If True, the resulting index will be labeled 0, 1, …, n - 1.
We can use the column_name function along with the operator to drop the specific value.
You could:
import numpy as np
df = df.set_index(['a', 'b'])
df = df.astype(str) + '| ' # There's a space ' ' to match the replace later
df = df.c.str.split('|', expand=True).stack().reset_index(-1, drop=True).replace(' ', np.nan).dropna().reset_index() # and replace also has a space ' '
to get:
a b 0
0 v f 3
1 v f 4
2 v f 5
3 v 2 6
4 v f 4
5 v f 5
Option 1
In [3404]: (df.set_index(['a', 'b'])['c']
.str.split('|', expand=True).stack()
.reset_index(name='c').drop('level_2', 1))
Out[3404]:
a b c
0 v f 3
1 v f 4
2 v f 5
3 v 2 6
4 v f 4
5 v f 5
Option 2 Using repeat
and loc
In [3503]: s = df.c.str.split('|')
In [3504]: df.loc[df.index.repeat(s.str.len())].assign(c=np.concatenate(s))
Out[3504]:
a b c
0 v f 3
0 v f 4
0 v f 5
1 v 2 6
2 v f 4
2 v f 5
Details
In [3505]: s
Out[3505]:
0 [3, 4, 5]
1 [6]
2 [4, 5]
Name: c, dtype: object
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With