问题描述
我有一个包含列表列表的列的数据框。所有基本列表都包含两个字符串。包含这些基本列表的列表中包含可变数量的列表。 例子:
A
0 [[1,1],[1,1]]
1 [[1,1]]
2 [[1,1]]
我想要一个有两列的新数据框。第一列包含每个基本列表中的第一项,第二列包含第二项。我是这样解决的:
df = pd.DataFrame(data = {'A': [[[1,1]],[[1,1]]]})
df2 = pd.DataFrame(columns = ['A','B'])
for x in df.A:
for i in x:
n = pd.DataFrame([i],columns = ('A','B'))
df2 = df2.append(n)
A B
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
我知道循环遍历数据框不好,但我不知道怎么做。以下是一些失败的尝试:
for x in df1:
df2 = [df2.append(pd.DataFrame([i],'B'))) for i in x]
df2 = df1.apply(lambda x: df2.append(pd.DataFrame([x[0]],columns = ['name','tid'])))
如果我让第一个列表理解起作用,我会尝试将 for 循环移动到第一个列表理解的末尾。
预先感谢您的帮助!
解决方法
这样做有用吗?
import pandas as pd
import itertools
df = pd.DataFrame(data = {'A': [[[1,1],[1,1]],[[1,1]]]})
a = []
b = []
for k in range(len(df)):
a.append([x[0] for x in df.iloc[k].A])
b.append([x[1] for x in df.iloc[k].A])
df2 = df2 = pd.DataFrame(data = {'A': list(itertools.chain(*a)),'B': list(itertools.chain(*b))})
结果:
>>> df2
A B
0 1 1
1 1 1
2 1 1
3 1 1
4 1 1
5 1 1
,
快速解决方案:
obj = df['A'].explode()
df1 = pd.DataFrame(obj.tolist(),index=obj.index,columns=['A','B'])
演示数据:
df = pd.Series([
[[1,2],2]],[[3,4]],3],4]]
],name='A').to_frame()
print(df)
A
0 [[1,2]]
1 [[3,4]]
2 [[1,4]]
使用 explode
将类似列表的每个元素转换为一行,复制索引值。
obj = df['A'].explode()
df1 = pd.DataFrame(obj.tolist(),'B'])
df_result = df1.groupby(level=0)[['A','B']].agg(list)
df_result
A B
0 [1,1] [2,2]
1 [3] [4]
2 [1,1,1] [2,3,4]
df1
A B
0 1 2
0 1 2
1 3 4
2 1 2
2 1 3
2 1 4
使用 .apply(pd.Series)
将包含列表元素的列转换为数据框。
df2 = df.A.apply(pd.Series)
print(df2)
0 1 2
0 [1,2] [1,2] NaN
1 [3,4] NaN NaN
2 [1,3] [1,4]