为列表列表中的每个列表创建一个 df
Posted
技术标签:
【中文标题】为列表列表中的每个列表创建一个 df【英文标题】:Create a df for each list of lists within a list of lists of lists 【发布时间】:2020-10-22 05:05:48 【问题描述】:我有一个列表列表和另一个列表
lslsls = [[[1,2,3],[11,12,13],[21,22,23],[1,2,3],[11,12,13],[21,22,23]],[[1,2,3],[11,12,13],[21,22,23],[1,2,3],[11,12,13],[21,22,23]],[[1,2,3],[11,12,13],[21,22,23],[1,2,3],[11,12,13],[21,22,23]]]
ls = ["a", "b", "c"]
我希望为“lslsls”中的每个列表列表创建一个 pandas 数据框,并且当我这样做时,将“ls”的每个元素添加到数据框的每一行。我可以单独执行此操作,即
import pandas as pd
df = pd.DataFrame(lslsls[0])
df["name"] = ls[0]
但是,我需要遍历“lslsls”中的所有列表列表,并将 ls 中的元素添加为一列。这将创建 3 个单独的 df,理想情况下我可以将它们命名为“ls”中的每个元素
所以最终得到:
import pandas as pd
a = pd.DataFrame(lslsls[0])
a["name"] = ls[0]
b = pd.DataFrame(lslsls[1])
b["name"] = ls[1]
c = pd.DataFrame(lslsls[2])
c["name"] = ls[2]
这是我的尝试:
for i in ls:
for p in lslsls:
i = pd.DataFrame(lslsls[p])
i["name"] = ls[i]
【问题讨论】:
【参考方案1】:一种方法
numpy.concatenate
和 numpy.repeat
#import numpy as np
(pd.DataFrame(np.concatenate(lslsls),
index=np.repeat(ls, tuple(map(len, lslsls))))
.rename_axis('Name').reset_index())
Name 0 1 2
0 a 1 2 3
1 a 11 12 13
2 a 21 22 23
3 a 1 2 3
4 a 11 12 13
5 a 21 22 23
6 b 1 2 3
7 b 11 12 13
8 b 21 22 23
9 b 1 2 3
10 b 11 12 13
11 b 21 22 23
12 c 1 2 3
13 c 11 12 13
14 c 21 22 23
15 c 1 2 3
16 c 11 12 13
17 c 21 22 23
或者
(pd.DataFrame(np.concatenate(lslsls))
.assign(Name=np.repeat(ls, tuple(map(len, lslsls)))))
0 1 2 Name
0 1 2 3 a
1 11 12 13 a
2 21 22 23 a
3 1 2 3 a
4 11 12 13 a
5 21 22 23 a
6 1 2 3 b
7 11 12 13 b
8 21 22 23 b
9 1 2 3 b
10 11 12 13 b
11 21 22 23 b
12 1 2 3 c
13 11 12 13 c
14 21 22 23 c
15 1 2 3 c
16 11 12 13 c
17 21 22 23 c
%%timeit
pd.DataFrame(np.concatenate(lslsls)).assign(Name=np.repeat(ls, tuple(map(len, lslsls))))
914 µs ± 84.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
(pd.DataFrame(np.concatenate(lslsls),
index=np.repeat(ls, tuple(map(len, lslsls))))
.rename_axis('Name').reset_index())
1.23 ms ± 12 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
df = pd.concat([pd.DataFrame(each_list).assign(name=Name)
for Name,each_list in zip(ls,lslsls)])
4.49 ms ± 105 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
【讨论】:
太棒了,我真的需要用 numpy 方法重构我的核心 python 代码,以获得如此多的性能! 我们有时都会忘记去 numpy :) @Datanovice 你可爱的解决方案的另一个玩法,同时避免assign
:df = pd.DataFrame(np.concatenate(lslsls)); df.insert(0, "Name", np.repeat(ls, len(lslsls[0])))
【参考方案2】:
我们可以使用 dict 理解通过压缩两个可迭代对象来在集合中创建数据帧。
然后我们可以链接assign
来创建您的专栏。
dfs = Name : pd.DataFrame(each_list).assign(name=Name)
for Name,each_list in zip(ls,lslsls)
print(dfs['a'])
0 1 2 name
0 1 2 3 a
1 11 12 13 a
2 21 22 23 a
3 1 2 3 a
4 11 12 13 a
5 21 22 23 a
print(dfs['b'])
0 1 2 name
0 1 2 3 b
1 11 12 13 b
2 21 22 23 b
3 1 2 3 b
4 11 12 13 b
5 21 22 23 b
如果您想要单个数据框,我们可以使用pd.concat
df = pd.concat([pd.DataFrame(each_list).assign(name=Name)
for Name,each_list in zip(ls,lslsls)])
print(df)
0 1 2 name
0 1 2 3 a
1 11 12 13 a
2 21 22 23 a
3 1 2 3 a
4 11 12 13 a
5 21 22 23 a
0 1 2 3 b
1 11 12 13 b
2 21 22 23 b
3 1 2 3 b
4 11 12 13 b
5 21 22 23 b
0 1 2 3 c
1 11 12 13 c
2 21 22 23 c
3 1 2 3 c
4 11 12 13 c
5 21 22 23 c
【讨论】:
啊,这太完美了,因为我要创建单独的数据框作为变量。考虑到我正在使用的数据集的大小,这会给我数千个变量。谢谢你 收藏很棒 :) 如果这回答了您的问题,请不要忘记接受它。 @DanynPatel以上是关于为列表列表中的每个列表创建一个 df的主要内容,如果未能解决你的问题,请参考以下文章
如何将 2 个列表的列表转换为 pandas 中的 2 列 df