代码之家  ›  专栏  ›  技术社区  ›  rpl

具有熊猫排列的多个嵌套列表

  •  2
  • rpl  · 技术社区  · 6 年前

    我有一个关于python的严肃问题。

    我有一些嵌套列表需要转换为pandas数据帧。看起来很容易,但是什么让我觉得很有挑战性: -列表很大(因此代码需要快速) -它们是嵌套的 -当它们嵌套时,我需要组合。

    所以有了这个输入:

    la =  ['a', 'b', 'c', 'd', 'e']
    lb = [[1], [2], [3, 33], [11,12,13], [4]]
    lc = [[1], [2, 22], [3], [11,12,13], [4]]
    

    我需要以下作为输出

    la      lb      lc
    a       1       1
    b       2       2
    b       2       22
    c       3       3
    c       33      3
    d       11      11
    d       11      12
    d       11      13
    d       12      11
    d       12      12
    d       12      13
    d       13      11
    d       13      12
    d       13      13
    e       4       4
    

    请注意,每当我有一个嵌套列表时,我都需要所有置换。 起初,我只是简单地尝试:

    import pandas as pd
    pd.DataFrame({'la' : [x for x in la],
                  'lb' : [x for x in lb],
                  'lc' : [x for x in lc]})
    

    但寻找需要扩展和实际扩展(一个巨大的)数据帧的行似乎比修补我创建数据帧的方式更难。

    我看了一些关于itertools的好帖子( Flattening a shallow list in Python ),文档( https://docs.python.org/3.6/library/itertools.html )和发电机( What does the "yield" keyword do? ),并得出如下结论:

    import itertools
    
    def f(la, lb, lc):
        tmp = len(la) == len(lb) == len(lc)
        if tmp:
            for item in range(len(la)):
                len_b = len(lb[item])
                len_c = len(lc[item])
                if ((len_b>1) or (len_c>1)):
                    yield list(itertools.product(la[item], lb[item], lc[item]))
                    ## above: list is not the result I need,
                    ##        without it it breaks (not an iterable)
                else:
                    yield (la[item], lb[item], lc[item])
        else:
            print('error: unequal length')
    

    我测试的

    my_gen =f(lit1, lit2, lit3)
    pd.DataFrame.from_records(my_gen)
    

    哪一个好当我 yield itertools (它没有长度),并在我强制转换后创建错误的数据结构 itertools公司 到一个iterable。

    我的问题如下:

    • 如何解决该问题 产量 惯性导航与制导 itertools公司 ?
    • 这是否有效?在实际应用中,我将通过解析文件来创建列表,它们将是巨大的。。。更高级的同事有什么性能提示或更好的解决方案吗?对不对,它坏了/行为不端,所以我甚至无法进行基准测试。。。
    • 逐个元素生成列表,然后使用 f 作用

    提前感谢您!

    2 回复  |  直到 6 年前
        1
  •  2
  •   Lambda    6 年前

    我有一个解决方案:

    import pandas as pd
    from itertools import product
    
    la =  ['a', 'b', 'c', 'd', 'e']
    lb = [[1], [2], [3, 33], [11,12,13], [4]]
    lc = [[1], [2, 22], [3], [11,12,13], [4]]
    
    list_product = reduce(lambda x, y: x + y, [list(product(*_)) for _ in zip(la,lb,lc)])
    df = pd.DataFrame(list_product, columns=["la", "lb", "lc"])
    print(df)
    

    结果:

        la  lb  lc
    0   a   1   1
    1   b   2   2
    2   b   2   22
    3   c   3   3
    4   c   33  3
    5   d   11  11
    6   d   11  12
    7   d   11  13
    8   d   12  11
    9   d   12  12
    10  d   12  13
    11  d   13  11
    12  d   13  12
    13  d   13  13
    14  e   4   4
    
        2
  •  0
  •   Jim Factor    6 年前

    这不是一个抽象的解决方案,但它确实得到了您想要的结果。我期待着看到一个更加以熊猫为中心的答案来解决这个问题,但同时也提出了这个问题。

    import pandas as pd
    la =  ['a', 'b', 'c', 'd', 'e']
    lb = [[1], [2], [3, 33], [11,12,13], [4]]
    lc = [[1], [2, 22], [3], [11,12,13], [4]]
    
    l1 = []
    l2 = []
    l3 = []
    
    l1Temp = []
    l2Temp = []
    l3Temp = []
    
    for i, listInt in enumerate(lb):
        if type(listInt == list):
            for j, item in enumerate(listInt):
                # print('%s - %s' % (lb[i], lc[i][j]))
                l1Temp.append(la[i])
                l2Temp.append(lb[i][j])
                l3Temp.append(lc[i])
                # print('%s - %s' % (l1[i], l2[i]))
        else:
            l1Temp.append(la[i])
            l2Temp.append(lb[i])
            l3Temp.append(lc[i])
            # print('%s - %s' % (lb[i], lc[i]))
    
    for i, listInt in enumerate(l3Temp):
        if type(listInt == list):
            for j, item in enumerate(listInt):
                l1.append(l1Temp[i])
                l2.append(l2Temp[i])
                l3.append(l3Temp[i][j])
        else:
            l1.append(l1Temp[i])
            l2.append(l2Temp[i])
            l3.append(l3Temp[i])
    
    for i, item in enumerate(l3):
        print('%s - %s - %s' % (l1[i], l2[i], l3[i]))
    
    df = pd.DataFrame({'la':[x for x in l1],
        'lb':[x for x in l2],
        'lc': [x for x in l3]})
    print(df)