取消嵌套(爆炸)pandas DataFrame中的多个列表列的有效方法

我正在将多个JSON对象读取到一个DataFrame中。问题在于某些列是列表。而且,数据非常大,因此我无法使用互联网上可用的解决方案。它们非常慢并且内存效率低下

这是我的数据的样子:

df = pd.DataFrame({'A': ['x1','x2','x3', 'x4'], 'B':[['v1','v2'],['v3','v4'],['v5','v6'],['v7','v8']], 'C':[['c1','c2'],['c3','c4'],['c5','c6'],['c7','c8']],'D':[['d1','d2'],['d3','d4'],['d5','d6'],['d7','d8']], 'E':[['e1','e2'],['e3','e4'],['e5','e6'],['e7','e8']]})

A B C D E

0 x1 [v1, v2] [c1, c2] [d1, d2] [e1, e2]

1 x2 [v3, v4] [c3, c4] [d3, d4] [e3, e4]

2 x3 [v5, v6] [c5, c6] [d5, d6] [e5, e6]

3 x4 [v7, v8] [c7, c8] [d7, d8] [e7, e8]

这就是我的数据的形状:(441079,12)

我想要的输出是:

    A       B          C           D           E

0 x1 v1 c1 d1 e1

0 x1 v2 c2 d2 e2

1 x2 v3 c3 d3 e3

1 x2 v4 c4 d4 e4

.....

编辑:标记为重复后,我想强调一个事实,在这个问题中,我正在寻找一种爆炸多列的 有效

方法。因此,批准的答案能够有效地爆炸非常大的数据集上的任意数量的列。另一个问题的答案无法解决(这就是我测试这些解决方案后问这个问题的原因)。

回答:

def explode(df, lst_cols, fill_value=''):

# make sure `lst_cols` is a list

if lst_cols and not isinstance(lst_cols, list):

lst_cols = [lst_cols]

# all columns except `lst_cols`

idx_cols = df.columns.difference(lst_cols)

# calculate lengths of lists

lens = df[lst_cols[0]].str.len()

if (lens > 0).all():

# ALL lists in cells aren't empty

return pd.DataFrame({

col:np.repeat(df[col].values, df[lst_cols[0]].str.len())

for col in idx_cols

}).assign(**{col:np.concatenate(df[col].values) for col in lst_cols}) \

.loc[:, df.columns]

else:

# at least one list in cells is empty

return pd.DataFrame({

col:np.repeat(df[col].values, df[lst_cols[0]].str.len())

for col in idx_cols

}).assign(**{col:np.concatenate(df[col].values) for col in lst_cols}) \

.append(df.loc[lens==0, idx_cols]).fillna(fill_value) \

.loc[:, df.columns]

用法:

In [82]: explode(df, lst_cols=list('BCDE'))

Out[82]:

A B C D E

0 x1 v1 c1 d1 e1

1 x1 v2 c2 d2 e2

2 x2 v3 c3 d3 e3

3 x2 v4 c4 d4 e4

4 x3 v5 c5 d5 e5

5 x3 v6 c6 d6 e6

6 x4 v7 c7 d7 e7

7 x4 v8 c8 d8 e8

以上是 取消嵌套(爆炸)pandas DataFrame中的多个列表列的有效方法 的全部内容, 来源链接: utcz.com/qa/416836.html

回到顶部