如何解窝(爆炸)在一个熊猫数据帧列,成多行

我有以下数据帧,其中一列是一个对象(列表类型单元格):

df = pd.DataFrame({'A': [1, 2], 'B': [[1, 2], [1, 2]]})

输出:

   A       B
0  1  [1, 2]
1  2  [1, 2]

我的期望输出是:

   A  B
0  1  1
1  1  2
3  2  1
4  2  2

我该怎么做才能做到这一点呢?


相关的问题

折叠列的列表,为每个列表元素创建一行

很好的问题和答案,但只处理一个列与列表(在我的回答自定义函数将工作于多个列,也接受的答案是使用最耗时的apply,这是不建议的,检查更多信息什么时候我应该(不)想要在我的代码中使用熊猫apply() ?)

117508 次浏览

我知道object dtype列使得数据很难用pandas函数转换。当我收到这样的数据时,第一个想到的就是“扁平化”。或者取消列的嵌套。

我使用pandas和Python函数来回答这类问题。如果你担心上述解决方案的速度,检查user3483203的回答,因为它使用numpy,大多数时候numpy更快。如果速度很重要,我推荐Cythonnumba


方法0 [pandas >= 0.25] 从熊猫0.25开始,如果你只需要爆炸一个列,你可以使用pandas.DataFrame.explode函数:

df.explode('B')


A  B
0  1  1
1  1  2
0  2  1
1  2  2

给定一个列中有空listNaN的数据框架。空列表不会导致问题,但NaN需要用list填充

df = pd.DataFrame({'A': [1, 2, 3, 4],'B': [[1, 2], [1, 2], [], np.nan]})
df.B = df.B.fillna({i: [] for i in df.index})  # replace NaN with []
df.explode('B')


A    B
0  1    1
0  1    2
1  2    1
1  2    2
2  3  NaN
3  4  NaN

< >强方法1 apply + pd.Series(容易理解,但在性能方面不建议使用。)

df.set_index('A').B.apply(pd.Series).stack().reset_index(level=0).rename(columns={0:'B'})
Out[463]:
A  B
0  1  1
1  1  2
0  2  1
1  2  2

< >强方法2 使用repeatDataFrame构造函数,重新创建你的数据帧(擅长性能,不擅长多列)

df=pd.DataFrame({'A':df.A.repeat(df.B.str.len()),'B':np.concatenate(df.B.values)})
df
Out[465]:
A  B
0  1  1
0  1  2
1  2  1
1  2  2

< >强方法2.1 例如,除了A,我们还有A.1 .....A.n。如果我们仍然使用上面的方法(方法2),则很难逐个重新创建列

解决方案:joinmerge,在“unnest”单列之后加上index

s=pd.DataFrame({'B':np.concatenate(df.B.values)},index=df.index.repeat(df.B.str.len()))
s.join(df.drop('B',1),how='left')
Out[477]:
B  A
0  1  1
0  2  1
1  1  2
1  2  2

如果需要列顺序与之前完全相同,则在末尾添加reindex

s.join(df.drop('B',1),how='left').reindex(columns=df.columns)

< >强方法3 重新创建list

pd.DataFrame([[x] + [z] for x, y in df.values for z in y],columns=df.columns)
Out[488]:
A  B
0  1  1
1  1  2
2  2  1
3  2  2

如果有两列以上,请使用

s=pd.DataFrame([[x] + [z] for x, y in zip(df.index,df.B) for z in y])
s.merge(df,left_on=0,right_index=True)
Out[491]:
0  1  A       B
0  0  1  1  [1, 2]
1  0  2  1  [1, 2]
2  1  1  2  [1, 2]
3  1  2  2  [1, 2]

< >强方法4 使用reindexloc

df.reindex(df.index.repeat(df.B.str.len())).assign(B=np.concatenate(df.B.values))
Out[554]:
A  B
0  1  1
0  1  2
1  2  1
1  2  2


#df.loc[df.index.repeat(df.B.str.len())].assign(B=np.concatenate(df.B.values))

< >强方法5 当列表只包含唯一值时:

df=pd.DataFrame({'A':[1,2],'B':[[1,2],[3,4]]})
from collections import ChainMap
d = dict(ChainMap(*map(dict.fromkeys, df['B'], df['A'])))
pd.DataFrame(list(d.items()),columns=df.columns[::-1])
Out[574]:
B  A
0  1  1
1  2  1
2  3  2
3  4  2

< >强方法6 使用numpy实现高性能:

newvalues=np.dstack((np.repeat(df.A.values,list(map(len,df.B.values))),np.concatenate(df.B.values)))
pd.DataFrame(data=newvalues[0],columns=df.columns)
A  B
0  1  1
1  1  2
2  2  1
3  2  2

< >强方法7 使用基函数itertools cyclechain:纯粹的python解决方案,只是为了好玩

from itertools import cycle,chain
l=df.values.tolist()
l1=[list(zip([x[0]], cycle(x[1])) if len([x[0]]) > len(x[1]) else list(zip(cycle([x[0]]), x[1]))) for x in l]
pd.DataFrame(list(chain.from_iterable(l1)),columns=df.columns)
A  B
0  1  1
1  1  2
2  2  1
3  2  2

泛化到多个列

df=pd.DataFrame({'A':[1,2],'B':[[1,2],[3,4]],'C':[[1,2],[3,4]]})
df
Out[592]:
A       B       C
0  1  [1, 2]  [1, 2]
1  2  [3, 4]  [3, 4]

Self-def功能:

def unnesting(df, explode):
idx = df.index.repeat(df[explode[0]].str.len())
df1 = pd.concat([
pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
df1.index = idx


return df1.join(df.drop(explode, 1), how='left')




unnesting(df,['B','C'])
Out[609]:
B  C  A
0  1  1  1
0  2  2  1
1  3  3  2
1  4  4  2

列unnest运算

以上所有方法都是在讨论< >强垂直< / >强取消嵌套和爆炸,如果你确实需要展开列表< >强劲水平< / >强,请使用pd.DataFrame构造函数检查

df.join(pd.DataFrame(df.B.tolist(),index=df.index).add_prefix('B_'))
Out[33]:
A       B       C  B_0  B_1
0  1  [1, 2]  [1, 2]    1    2
1  2  [3, 4]  [3, 4]    3    4

更新的功能

def unnesting(df, explode, axis):
if axis==1:
idx = df.index.repeat(df[explode[0]].str.len())
df1 = pd.concat([
pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
df1.index = idx


return df1.join(df.drop(explode, 1), how='left')
else :
df1 = pd.concat([
pd.DataFrame(df[x].tolist(), index=df.index).add_prefix(x) for x in explode], axis=1)
return df1.join(df.drop(explode, 1), how='left')

测试输出

unnesting(df, ['B','C'], axis=0)
Out[36]:
B0  B1  C0  C1  A
0   1   2   1   2  1
1   3   4   3   4  2

更新2021-02-17原有爆炸功能

def unnesting(df, explode, axis):
if axis==1:
df1 = pd.concat([df[x].explode() for x in explode], axis=1)
return df1.join(df.drop(explode, 1), how='left')
else :
df1 = pd.concat([
pd.DataFrame(df[x].tolist(), index=df.index).add_prefix(x) for x in explode], axis=1)
return df1.join(df.drop(explode, 1), how='left')

< em >选项1 < / em >

如果另一列中的所有子列表都是相同的长度,numpy在这里是一个有效的选项:

vals = np.array(df.B.values.tolist())
a = np.repeat(df.A, vals.shape[1])


pd.DataFrame(np.column_stack((a, vals.ravel())), columns=df.columns)

   A  B
0  1  1
1  1  2
2  2  1
3  2  2

< em >选项2 < / em >

如果子列表有不同的长度,你需要额外的步骤:

vals = df.B.values.tolist()
rs = [len(r) for r in vals]
a = np.repeat(df.A, rs)


pd.DataFrame(np.column_stack((a, np.concatenate(vals))), columns=df.columns)

   A  B
0  1  1
1  1  2
2  2  1
3  2  2

< em >选项3 < / em >

我尝试将其泛化,以平铺N列和平铺M列,我将在后面使其更有效:

df = pd.DataFrame({'A': [1,2,3], 'B': [[1,2], [1,2,3], [1]],
'C': [[1,2,3], [1,2], [1,2]], 'D': ['A', 'B', 'C']})

   A          B          C  D
0  1     [1, 2]  [1, 2, 3]  A
1  2  [1, 2, 3]     [1, 2]  B
2  3        [1]     [1, 2]  C

def unnest(df, tile, explode):
vals = df[explode].sum(1)
rs = [len(r) for r in vals]
a = np.repeat(df[tile].values, rs, axis=0)
b = np.concatenate(vals.values)
d = np.column_stack((a, b))
return pd.DataFrame(d, columns = tile +  ['_'.join(explode)])


unnest(df, ['A', 'D'], ['B', 'C'])

    A  D B_C
0   1  A   1
1   1  A   2
2   1  A   1
3   1  A   2
4   1  A   3
5   2  B   1
6   2  B   2
7   2  B   3
8   2  B   1
9   2  B   2
10  3  C   1
11  3  C   1
12  3  C   2

< em > < / em >功能

def wen1(df):
return df.set_index('A').B.apply(pd.Series).stack().reset_index(level=0).rename(columns={0: 'B'})


def wen2(df):
return pd.DataFrame({'A':df.A.repeat(df.B.str.len()),'B':np.concatenate(df.B.values)})


def wen3(df):
s = pd.DataFrame({'B': np.concatenate(df.B.values)}, index=df.index.repeat(df.B.str.len()))
return s.join(df.drop('B', 1), how='left')


def wen4(df):
return pd.DataFrame([[x] + [z] for x, y in df.values for z in y],columns=df.columns)


def chris1(df):
vals = np.array(df.B.values.tolist())
a = np.repeat(df.A, vals.shape[1])
return pd.DataFrame(np.column_stack((a, vals.ravel())), columns=df.columns)


def chris2(df):
vals = df.B.values.tolist()
rs = [len(r) for r in vals]
a = np.repeat(df.A.values, rs)
return pd.DataFrame(np.column_stack((a, np.concatenate(vals))), columns=df.columns)

< em > < / em >时间

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from timeit import timeit


res = pd.DataFrame(
index=['wen1', 'wen2', 'wen3', 'wen4', 'chris1', 'chris2'],
columns=[10, 50, 100, 500, 1000, 5000, 10000],
dtype=float
)


for f in res.index:
for c in res.columns:
df = pd.DataFrame({'A': [1, 2], 'B': [[1, 2], [1, 2]]})
df = pd.concat([df]*c)
stmt = '{}(df)'.format(f)
setp = 'from __main__ import df, {}'.format(f)
res.at[f, c] = timeit(stmt, setp, number=50)


ax = res.div(res.min()).T.plot(loglog=True)
ax.set_xlabel("N")
ax.set_ylabel("time (relative)")

< em > < / em >性能

enter image description here

有些东西不太推荐(至少在这种情况下有用):

df=pd.concat([df]*2).sort_index()
it=iter(df['B'].tolist()[0]+df['B'].tolist()[0])
df['B']=df['B'].apply(lambda x:next(it))

__abc0 + __abc1 + __abc2 + __abc3 + __abc4。

现在:

print(df)

是:

   A  B
0  1  1
0  1  2
1  2  1
1  2  2

如果关心索引:

df=df.reset_index(drop=True)

现在:

print(df)

是:

   A  B
0  1  1
1  1  2
2  2  1
3  2  2

一种替代方法是在列的行上应用meshgrid食谱来取消嵌套:

import numpy as np
import pandas as pd




def unnest(frame, explode):
def mesh(values):
return np.array(np.meshgrid(*values)).T.reshape(-1, len(values))


data = np.vstack(mesh(row) for row in frame[explode].values)
return pd.DataFrame(data=data, columns=explode)




df = pd.DataFrame({'A': [1, 2], 'B': [[1, 2], [1, 2]]})
print(unnest(df, ['A', 'B']))  # base
print()


df = pd.DataFrame({'A': [1, 2], 'B': [[1, 2], [3, 4]], 'C': [[1, 2], [3, 4]]})
print(unnest(df, ['A', 'B', 'C']))  # multiple columns
print()


df = pd.DataFrame({'A': [1, 2, 3], 'B': [[1, 2], [1, 2, 3], [1]],
'C': [[1, 2, 3], [1, 2], [1, 2]], 'D': ['A', 'B', 'C']})


print(unnest(df, ['A', 'B']))  # uneven length lists
print()
print(unnest(df, ['D', 'B']))  # different types
print()

输出

   A  B
0  1  1
1  1  2
2  2  1
3  2  2


A  B  C
0  1  1  1
1  1  2  1
2  1  1  2
3  1  2  2
4  2  3  3
5  2  4  3
6  2  3  4
7  2  4  4


A  B
0  1  1
1  1  2
2  2  1
3  2  2
4  2  3
5  3  1


D  B
0  A  1
1  A  2
2  B  1
3  B  2
4  B  3
5  C  1

我的5美分:

df[['B', 'B2']] = pd.DataFrame(df['B'].values.tolist())


df[['A', 'B']].append(df[['A', 'B2']].rename(columns={'B2': 'B'}),
ignore_index=True)

还有5个

df[['B1', 'B2']] = pd.DataFrame([*df['B']]) # if values.tolist() is too boring


(pd.wide_to_long(df.drop('B', 1), 'B', 'A', '')
.reset_index(level=1, drop=True)
.reset_index())

两者的结果是一样的

   A  B
0  1  1
1  2  1
2  1  2
3  2  2

因为通常子列表的长度是不同的,join/merge的计算成本要高得多。我对不同长度的子列表和更多正常列重新测试了该方法。

MultiIndex也应该是一种更简单的编写方法,并且具有与numpy方法几乎相同的性能。

令人惊讶的是,在我的实现理解方式有最好的表现。

def stack(df):
return df.set_index(['A', 'C']).B.apply(pd.Series).stack()




def comprehension(df):
return pd.DataFrame([x + [z] for x, y in zip(df[['A', 'C']].values.tolist(), df.B) for z in y])




def multiindex(df):
return pd.DataFrame(np.concatenate(df.B.values), index=df.set_index(['A', 'C']).index.repeat(df.B.str.len()))




def array(df):
return pd.DataFrame(
np.column_stack((
np.repeat(df[['A', 'C']].values, df.B.str.len(), axis=0),
np.concatenate(df.B.values)
))
)




import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from timeit import timeit


res = pd.DataFrame(
index=[
'stack',
'comprehension',
'multiindex',
'array',
],
columns=[1000, 2000, 5000, 10000, 20000, 50000],
dtype=float
)


for f in res.index:
for c in res.columns:
df = pd.DataFrame({'A': list('abc'), 'C': list('def'), 'B': [['g', 'h', 'i'], ['j', 'k'], ['l']]})
df = pd.concat([df] * c)
stmt = '{}(df)'.format(f)
setp = 'from __main__ import df, {}'.format(f)
res.at[f, c] = timeit(stmt, setp, number=20)


ax = res.div(res.min()).T.plot(loglog=True)
ax.set_xlabel("N")
ax.set_ylabel("time (relative)")

性能

各方法对应的相对时间 . bbb

df=pd.DataFrame({'A':[1,2],'B':[[1,2],[1,2]]})


pd.concat([df['A'], pd.DataFrame(df['B'].values.tolist())], axis = 1)\
.melt(id_vars = 'A', value_name = 'B')\
.dropna()\
.drop('variable', axis = 1)


A   B
0   1   1
1   2   1
2   1   2
3   2   2

对我想到的这个方法有什么意见吗?或者同时做concat和melt被认为太“昂贵”?

df=pd.DataFrame({'A':[1,2],'B':[[1,2],[1,2]]})


out = pd.concat([df.loc[:,'A'],(df.B.apply(pd.Series))], axis=1, sort=False)


out = out.set_index('A').stack().droplevel(level=1).reset_index().rename(columns={0:"B"})


A    B
0    1   1
1    1   2
2    2   1
3    2   2
  • 如果您不希望创建中间对象,可以将其实现为一行
# Here's the answer to the related question in:
# https://stackoverflow.com/q/56708671/11426125


# initial dataframe
df12=pd.DataFrame({'Date':['2007-12-03','2008-09-07'],'names':
[['Peter','Alex'],['Donald','Stan']]})


# convert dataframe to array for indexing list values (names)
a = np.array(df12.values)


# create a new, dataframe with dimensions for unnested
b = np.ndarray(shape = (4,2))
df2 = pd.DataFrame(b, columns = ["Date", "names"], dtype = str)


# implement loops to assign date/name values as required
i = range(len(a[0]))
j = range(len(a[0]))
for x in i:
for y in j:
df2.iat[2*x+y, 0] = a[x][0]
df2.iat[2*x+y, 1] = a[x][1][y]


# set Date column as Index
df2.Date=pd.to_datetime(df2.Date)
df2.index=df2.Date
df2.drop('Date',axis=1,inplace =True)

我把这个问题推广了一下,以便适用于更多的专栏。

我的解决方案的总结:

In[74]: df
Out[74]:
A   B             C             columnD
0  A1  B1  [C1.1, C1.2]                D1
1  A2  B2  [C2.1, C2.2]  [D2.1, D2.2, D2.3]
2  A3  B3            C3        [D3.1, D3.2]


In[75]: dfListExplode(df,['C','columnD'])
Out[75]:
A   B     C columnD
0  A1  B1  C1.1    D1
1  A1  B1  C1.2    D1
2  A2  B2  C2.1    D2.1
3  A2  B2  C2.1    D2.2
4  A2  B2  C2.1    D2.3
5  A2  B2  C2.2    D2.1
6  A2  B2  C2.2    D2.2
7  A2  B2  C2.2    D2.3
8  A3  B3    C3    D3.1
9  A3  B3    C3    D3.2

完整的例子:

其余的是化妆品(多列爆炸,处理字符串而不是爆炸列中的列表,…)。

import pandas as pd
import numpy as np


df=pd.DataFrame( {'A': ['A1','A2','A3'],
'B': ['B1','B2','B3'],
'C': [ ['C1.1','C1.2'],['C2.1','C2.2'],'C3'],
'columnD': [ 'D1',['D2.1','D2.2', 'D2.3'],['D3.1','D3.2']],
})
print('df',df, sep='\n')


def dfListExplode(df, explodeKeys):
if not isinstance(explodeKeys, list):
explodeKeys=[explodeKeys]
# recursive handling of explodeKeys
if len(explodeKeys)==0:
return df
elif len(explodeKeys)==1:
explodeKey=explodeKeys[0]
else:
return dfListExplode( dfListExplode(df, explodeKeys[:1]), explodeKeys[1:])
# perform explosion/unnesting for key: explodeKey
dfPrep=df[explodeKey].apply(lambda x: x if isinstance(x,list) else [x]) #casts all elements to a list
dfIndExpl=pd.DataFrame([[x] + [z] for x, y in zip(dfPrep.index,dfPrep.values) for z in y ], columns=['explodedIndex',explodeKey])
dfMerged=dfIndExpl.merge(df.drop(explodeKey, axis=1), left_on='explodedIndex', right_index=True)
dfReind=dfMerged.reindex(columns=list(df))
return dfReind


dfExpl=dfListExplode(df,['C','columnD'])
print('dfExpl',dfExpl, sep='\n')

感谢WeNYoBen的回答

通过添加explode()方法,分解一个类似列表的列:

df = pd.DataFrame({'A': [1, 2], 'B': [[1, 2], [1, 2]]})
df.explode('B')

:

   A  B
0  1  1
0  1  2
1  2  1
1  2  2

在我的例子中,有多个列要爆炸,并且需要取消嵌套的数组有变量长度。

我最终应用了新的pandas 0.25 explode函数两次,然后删除生成的重复项,它完成了工作!

df = df.explode('A')
df = df.explode('B')
df = df.drop_duplicates()

问题的设置

假设有多个列,其中包含不同长度的对象

df = pd.DataFrame({
'A': [1, 2],
'B': [[1, 2], [3, 4]],
'C': [[1, 2], [3, 4, 5]]
})


df


A       B          C
0  1  [1, 2]     [1, 2]
1  2  [3, 4]  [3, 4, 5]

当长度相同时,我们很容易假设不同的元素重合,并且应该“压缩”在一起。

   A       B          C
0  1  [1, 2]     [1, 2]  # Typical to assume these should be zipped [(1, 1), (2, 2)]
1  2  [3, 4]  [3, 4, 5]

然而,当我们看到不同长度的对象时,这个假设就会受到挑战,我们应该“压缩”吗?如果是的话,我们如何处理其中一个对象中的多余部分呢?,也许我们想要所有对象的乘积。这将迅速扩大规模,但可能正是人们想要的。

   A       B          C
0  1  [1, 2]     [1, 2]
1  2  [3, 4]  [3, 4, 5]  # is this [(3, 3), (4, 4), (None, 5)]?

   A       B          C
0  1  [1, 2]     [1, 2]
1  2  [3, 4]  [3, 4, 5]  # is this [(3, 3), (3, 4), (3, 5), (4, 3), (4, 4), (4, 5)]

这个函数

此函数基于参数优雅地处理zipproduct,并根据具有zip_longest的最长对象的长度假设为zip

from itertools import zip_longest, product


def xplode(df, explode, zipped=True):
method = zip_longest if zipped else product


rest = {*df} - {*explode}


zipped = zip(zip(*map(df.get, rest)), zip(*map(df.get, explode)))
tups = [tup + exploded
for tup, pre in zipped
for exploded in method(*pre)]


return pd.DataFrame(tups, columns=[*rest, *explode])[[*df]]

压缩

xplode(df, ['B', 'C'])


A    B  C
0  1  1.0  1
1  1  2.0  2
2  2  3.0  3
3  2  4.0  4
4  2  NaN  5

产品

xplode(df, ['B', 'C'], zipped=False)


A  B  C
0  1  1  1
1  1  1  2
2  1  2  1
3  1  2  2
4  2  3  3
5  2  3  4
6  2  3  5
7  2  4  3
8  2  4  4
9  2  4  5

新设置

稍微改变一下这个例子

df = pd.DataFrame({
'A': [1, 2],
'B': [[1, 2], [3, 4]],
'C': 'C',
'D': [[1, 2], [3, 4, 5]],
'E': [('X', 'Y', 'Z'), ('W',)]
})


df


A       B  C          D          E
0  1  [1, 2]  C     [1, 2]  (X, Y, Z)
1  2  [3, 4]  C  [3, 4, 5]       (W,)

压缩

xplode(df, ['B', 'D', 'E'])


A    B  C    D     E
0  1  1.0  C  1.0     X
1  1  2.0  C  2.0     Y
2  1  NaN  C  NaN     Z
3  2  3.0  C  3.0     W
4  2  4.0  C  4.0  None
5  2  NaN  C  5.0  None

产品

xplode(df, ['B', 'D', 'E'], zipped=False)


A  B  C  D  E
0   1  1  C  1  X
1   1  1  C  1  Y
2   1  1  C  1  Z
3   1  1  C  2  X
4   1  1  C  2  Y
5   1  1  C  2  Z
6   1  2  C  1  X
7   1  2  C  1  Y
8   1  2  C  1  Z
9   1  2  C  2  X
10  1  2  C  2  Y
11  1  2  C  2  Z
12  2  3  C  3  W
13  2  3  C  4  W
14  2  3  C  5  W
15  2  4  C  3  W
16  2  4  C  4  W
17  2  4  C  5  W

我有另一个好方法来解决这个问题当你有不止一列要爆炸的时候。

df=pd.DataFrame({'A':[1,2],'B':[[1,2],[1,2]], 'C':[[1,2,3],[1,2,3]]})


print(df)
A       B          C
0  1  [1, 2]  [1, 2, 3]
1  2  [1, 2]  [1, 2, 3]

我想爆炸B和C列,首先爆炸B,第二爆炸C,然后从原来的df中去掉B和C。之后,我将在3个dfs上做一个索引连接。

explode_b = df.explode('B')['B']
explode_c = df.explode('C')['C']
df = df.drop(['B', 'C'], axis=1)
df = df.join([explode_b, explode_c])

下面是一个简单的水平爆炸函数,基于@BEN_YO的答案。

import typing
import pandas as pd


def horizontal_explode(df: pd.DataFrame, col_name: str, new_columns: typing.Union[list, None]=None) -> pd.DataFrame:
t = pd.DataFrame(df[col_name].tolist(), columns=new_columns, index=df.index)
return pd.concat([df, t], axis=1)


运行示例:

items = [
["1", ["a", "b", "c"]],
["2", ["d", "e", "f"]]
]


df = pd.DataFrame(items, columns = ["col1", "col2"])
print(df)


t = horizontal_explode(df=df, col_name="col2")
del t["col2"]
print(t)


t = horizontal_explode(df=df, col_name="col2", new_columns=["new_col1", "new_col2", "new_col3"])
del t["col2"]
print(t)

这是相关的输出:

  col1       col2
0    1  [a, b, c]
1    2  [d, e, f]


col1  0  1  2
0    1  a  b  c
1    2  d  e  f


col1 new_col1 new_col2 new_col3
0    1        a        b        c
1    2        d        e        f
 demo = {'set1':{'t1':[1,2,3],'t2':[4,5,6],'t3':[7,8,9]}, 'set2':{'t1':[1,2,3],'t2':[4,5,6],'t3':[7,8,9]}, 'set3': {'t1':[1,2,3],'t2':[4,5,6],'t3':[7,8,9]}}
df = pd.DataFrame.from_dict(demo, orient='index')


print(df.head())
my_list=[]
df2=pd.DataFrame(columns=['set','t1','t2','t3'])


for key,item in df.iterrows():
t1=item.t1
t2=item.t2
t3=item.t3
mat1=np.matrix([t1,t2,t3])
row1=[key,mat1[0,0],mat1[0,1],mat1[0,2]]
df2.loc[len(df2)]=row1
row2=[key,mat1[1,0],mat1[1,1],mat1[1,2]]
df2.loc[len(df2)]=row2
row3=[key,mat1[2,0],mat1[2,1],mat1[2,2]]
df2.loc[len(df2)]=row3


print(df2)


set t1 t2 t3
0  set1  1  2  3
1  set1  4  5  6
2  set1  7  8  9
3  set2  1  2  3
4  set2  4  5  6
5  set2  7  8  9
6  set3  1  2  3
7  set3  4  5  6
8  set3  7  8  9