问题描述
import pandas as pd
df = pd.DataFrame({'a':[1,2,3],'b':[[1,[1,3]],'c': [[4,5,6],[4,6]]})
我想爆炸带有b和c列的数据框。我知道,如果我们只使用一列,那么我们可以做到
df.explode('column_name')
output = pd.DataFrame({'a':[1,1,3,'b':[1,'c': [4,6,4,6]})
我尝试过
df.explode(['a','b'])
但是它不起作用,给了我一个
ValueError: column must be a scalar.
谢谢。
解决方法
让我们尝试
df=pd.concat([df[x].explode() for x in ['b','c']],axis=1).join(df[['a']]).reindex(columns=df.columns)
Out[179]:
a b c
0 1 1 4
0 1 2 5
0 1 3 6
1 2 1 4
1 2 2 5
1 2 3 6
2 3 1 4
2 3 2 5
2 3 3 6
,
您可以使用itertools chain和zip来获得结果:
pd.DataFrame(chain.from_iterable(zip([a] * df.shape[-1],b,c)
for a,c in df.to_numpy()))
0 1 2
0 1 1 4
1 1 2 5
2 1 3 6
3 2 1 4
4 2 2 5
5 2 3 6
6 3 1 4
7 3 2 5
8 3 3 6
,
@Ben的列表理解最快。但是,如果您不太关心速度,可以将apply
与pd.Series.explode
df.set_index('a').apply(pd.Series.explode).reset_index()
或者简单地apply
。在非列表列上,它将返回原始值
df.apply(pd.Series.explode).reset_index(drop=True)
Out[42]:
a b c
0 1 1 4
1 1 2 5
2 1 3 6
3 2 1 4
4 2 2 5
5 2 3 6
6 3 1 4
7 3 2 5
8 3 3 6