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

对压缩矩阵元素重新排序

  •  0
  • flywire  · 技术社区  · 7 年前

    我在一个可变大小的电子表格中有两个匹配的大小矩阵,一个有数据项,另一个有标记项可以处理。在压缩项目后,它们的处理顺序不方便。如何对项目进行压缩以便将项目和启用放在一起?

    希望只是 zipper = zip(output, doit) 但它失败得很严重,如输出所示。

    预期输出和压缩矩阵如下所示。

    from __future__ import print_function
    from openpyxl import Workbook
    wb = Workbook()
    ws = wb.active
    
    rows = [
        ['Number', 'Batch 1', 'Batch 2'],
        [2, 40, 30],
        [3, 40, 25],
        [4, 50, 30],
        [5, 30, 10],
    ]
    enabled = [
        [0, 0, 0],
        [0, 1, 0],
        [1, 1, 0],
        [0, 0, 1],
        [0, 1, 0],
    ]
    
    for row in rows:
        ws.append(row)
    output = []
    for i, row in enumerate(ws['B1:C5']):
        output.append([])
        for cell in row:
            output[i].append(cell.value)
    
    for row in enabled:
        ws.append(row)
    doit = []
    for i, row in enumerate(ws['A6:B10']):
        doit.append([])
        for cell in row:
            doit[i].append(cell.value)
    
    zipper = zip(output, doit)
    print(zipper)
    
    for i in range(len(output[0])):
        print(">>Do column")
        for j in range(len(output)):
            if doit[j][i]:
                print(output[j][i])
    

    产量

    [([u'Batch 1', u'Batch 2'], [0, 0]), ([40, 30], [0, 1]), ([40, 25], [1, 1]), ([50, 30], [0, 0]), ([30, 10], [0, 1])]
    >>Do column
    40
    >>Do column
    30
    25
    10
    

    我希望拉链看起来像:

    [
    [(0, u'Batch 1'), (0, u'Batch 2')]
    [(0, 40), (1, 30)]
    [(1, 40), (1, 25)]
    [(0, 50), (0, 30)]
    [(0, 30), (1, 10)]
    ]
    

    没有成功:

    # Flatten
    zipper = zip(sum(output, []), sum(doit, []))
    # Reassemble array
    y = zip(*[iter(zipper)]*2)
    print(list(y))
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   bobrobbob    7 年前

    这应该管用

    zipper = [[(a, c), (b, d)] for [a, b], [c, d] in zip(output, doit)]
    inverse_zipper = [[(c, a), (d, b)] for [a, b], [c, d] in zip(output, doit)]
    

    作为旧线路的替代品

    zipper = zip(output, doit)
    

    标准类型

    [] 表示 list () tuple . python类型的文档是 here . 主要的区别是元组是不可变的。在这里,我尊重你想要的输出


    列表理解

    zipper = [[(a, c), (b, d)] for [a, b], [c, d] in zip(output, doit)]
    

    等于

    zipper = []
    for [a, b], [c, d] in zip(output, doit):
        zipper.append([(a, c), (b, d)])
    

    拆包

    解包是一种快速的任务。 a, b = [4,7] 等于

    some_list = [4,7]
    a = some_list[0]
    b = some_list[1]
    

    两者都分配4到A和7到B

    你知道的输出 zip(output, doit) [([u'Batch 1', u'Batch 2'], [0, 0]), ([40, 30], [0, 1]), ([40, 25], [1, 1]), ([50, 30], [0, 0]), ([30, 10], [0, 1])] 所以如果你这样做的话 for row in zip(output, doit): , row 将采用以下形式 ([40, 30], [0, 1]) 可以解包为 [a, b], [c, d] 你可以直接在你的for语句中进行分配 for [a, b], [c, d] in zip(output, doit)