【问题标题】:Create a df for each list of lists within a list of lists of lists为列表列表中的每个列表创建一个 df
【发布时间】: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]
        

【问题讨论】:

    标签: pandas list dataframe for-loop


    【解决方案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
    猜你喜欢
    • 2015-01-31
    • 1970-01-01
    • 2022-12-12
    • 2016-02-14
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多