21

I have DF that has multiple columns. Two of the columns are list of the same len.( col2 and col3 are list. the len of the list is the same).

My goal is to list each element on it's own row.

I can use the df.explode(). but it only accepts one column. However, I want the pair of the two columns to be 'exploded'. If I do df.explode('col2') and then df.explode('col3'), it results it 9 rows instead of 3.

Original DF

col0      col1        col2        col3
1       aa          [1,2,3]     [1.1,2.2,3.3]
2       bb          [4,5,6]     [4.4,5.5,6.6]
3       cc          [7,8,9]     [7.7,8.8,9.9]
3       cc          [7,8,9]     [7.7,8.8,9.9]

End DataFrame

id      col1        col2        col3
1       aa          1           1.1
1       aa          2           2.2
1       aa          3           3.3
2       bb          4           4.4
2       bb          5           5.5
2       bb          6           6.6
3       cc          ...         ...

Update None of the column have unique values, so can't be used as index.

Imsa
  • 1,105
  • 2
  • 17
  • 39
  • Better answer can be found [`here`](https://stackoverflow.com/questions/67097110/convert-elements-in-lists-to-separate-rows/67097208#67097208). No need to use `set_index` and `reset_index`. – Mayank Porwal Apr 14 '21 at 18:43

2 Answers2

19

You could set col1 as index and apply pd.Series.explode across the columns:

df.set_index('col1').apply(pd.Series.explode).reset_index()

Or:

df.apply(pd.Series.explode)


   col1 col2 col3
0    aa    1  1.1
1    aa    2  2.2
2    aa    3  3.3
3    bb    4  4.4
4    bb    5  5.5
5    bb    6  6.6
6    cc    7  7.7
7    cc    8  8.8
8    cc    9  9.9
9    cc    7  7.7
10   cc    8  8.8
11   cc    9  9.9
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
yatu
  • 86,083
  • 12
  • 84
  • 139
6

I borrowed this solution from other answers (forgot where):

df.explode(['col2', 'col3']).

The advantage: faster than the apply solution.

Make sure both col2 and col3 have the same number of elements in cells in the same row.

Jia Gao
  • 1,172
  • 3
  • 13
  • 26