为列表列表中的每个列表创建一个 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.concatenatenumpy.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 你可爱的解决方案的另一个玩法,同时避免assigndf = 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的主要内容,如果未能解决你的问题,请参考以下文章

读取 df,拆分每个单元格并附加到列表

使用列表推导对数据框列表中的数据框进行编号

将列表附加为数据框行

如何将 2 个列表的列表转换为 pandas 中的 2 列 df

遍历 pandas 数据框中的行并匹配列表中的元组并创建一个新的 df 列

将dict列表转换为pandas中的行[重复]