【问题标题】:How to aggregate the elements in a nested list如何聚合嵌套列表中的元素
【发布时间】:2021-06-16 12:14:08
【问题描述】:

我有一个列表如下:

original_list = [['B_S', 'O', 'O', 'O'],
                 ['B_S', 'O', 'O', 'O'],
                 ['O', 'O', 'B_S', 'O'],

                 ['O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O'],

                 ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'B_S', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O']]

我想根据大多数元素将每三个列表聚合为一个列表。也就是说,如果两个位置具有相同的元素,则新列表将在相同位置采用相同的元素。 期望的输出应该是这样的:

desired_output = [['B_S', 'O', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O']]

我已经尝试过这个复杂的功能:

def collect_labels(lab_user):

  def aggregate_labels(a,b,c):
     aggregated_list = []
     # iterate over 3 lists
     for x,y,z in zip(a, b, c):
        if x != 'O':
          aggregated_list.append(x)
        elif y != 'O':
          aggregated_list.append(y)
        #elif z != 'O':
          #aggregated_list.append(z)  # you can improve the code
        else:
          aggregated_list.append(z)
     return aggregated_list

  result = [aggregate_labels(lab_user[i], lab_user[i+1], lab_user[i+2]) for i in range(0,len(lab_user)-2, 3)] 
  return result

但它返回错误的结果:

wrong_result= [['B_S', 'O', 'O', 'O'],
               ['O', 'O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O'],
               ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'B_S', 'O', 'O']]

如果您能帮助我更正我的代码,我将不胜感激!

【问题讨论】:

  • [[statistics.mode(i) for i in zip(*j)] for j in (original_list[i*3:i*3+3] for i in range(len(original_list)//3))]

标签: python list function


【解决方案1】:

问题中最难的部分是将您的列表分成三个块:

>>> [original_list[i*3:i*3+3] for i in range(len(original_list)//3)]
[[['B_S', 'O', 'O', 'O'], ['B_S', 'O', 'O', 'O'], ['O', 'O', 'B_S', 'O']], 
[['O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O', 'O', 'O'], ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O', 'O'], ['O', 'O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O']], 
[['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'B_S', 'O', 'O'], ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O'], ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O']]]

不过,一旦你有了它,你就可以使用zip 对你想要比较的项目进行分组:

>>> chunks = [original_list[i*3:i*3+3] for i in range(len(original_list)//3)]
>>> [list(zip(*j)) for j in chunks]
[[('B_S', 'B_S', 'O'), ('O', 'O', 'O'), ('O', 'O', 'B_S'), ('O', 'O', 'O')],
[('O', 'O', 'O'), ('O', 'O', 'O'), ('O', 'O', 'O'), ('O', 'O', 'O'), ('B_S', 'O', 'O'), ('O', 'B_S', 'O'), ('O', 'O', 'B_S'), ('O', 'O', 'O'), ('O', 'O', 'O'), ('O', 'O', 'O')], 
[('O', 'O', 'O'), ('O', 'O', 'O'), ('O', 'O', 'O'), ('O', 'O', 'O'), ('O', 'O', 'O'), ('B_S', 'B_S', 'B_S'), ('O', 'O', 'O'), ('O', 'O', 'O'), ('B_S', 'B_S', 'B_S'), ('B_S', 'O', 'O'), ('O', 'O', 'O'), ('O', 'O', 'O')]]

然后您只想在每个压缩元组中选择出现频率最高的项目 -- 也就是 statistics.mode:

>>> import statistics
>>> [[statistics.mode(i) for i in zip(*j)] for j in chunks]
[['B_S', 'O', 'O', 'O'], 
['O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O'], 
['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O']]

或全部:

from statistics import mode

original_list = [['B_S', 'O', 'O', 'O'],
                 ['B_S', 'O', 'O', 'O'],
                 ['O', 'O', 'B_S', 'O'],

                 ['O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O'],

                 ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'B_S', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O']]
CHUNK_LEN = 3

desired_output = [
    [mode(i) for i in zip(*j)] 
    for j in (
        original_list[i*CHUNK_LEN:(i+1)*CHUNK_LEN] 
        for i in range(len(original_list)//CHUNK_LEN)
    )
]

显然,如果您可以将original_list 正确分组在前面,那就容易多了:

from statistics import mode

original_list = [[['B_S', 'O', 'O', 'O'],
                 ['B_S', 'O', 'O', 'O'],
                 ['O', 'O', 'B_S', 'O']],

                 [['O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O']],

                 [['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'B_S', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O'],
                 ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O']]]

desired_output = [
    [mode(i) for i in zip(*j)] 
    for j in original_list
]

【讨论】:

    【解决方案2】:

    使用循环的更广泛的解决方案:

    def merge_result(data):
        ar = []
        for i in range(0, len(data)-2, 3):
            temp = []        
            for j in range(len(data[i])):
                if data[i][j] == data[i+1][j]:
                    temp.append(data[i][j])
                elif data[i+2][j] == data[i+1][j]:
                    temp.append(data[i+1][j])
                elif data[i][j] == data[i+2][j]:
                    temp.append(data[i][j])
                else:
                    temp.append('O')
            ar.append(temp)
        return ar
    
    if __name__ == "__main__":
        original_list = [['B_S', 'O', 'O', 'O'],
                     ['B_S', 'O', 'O', 'O'],
                     ['O', 'O', 'B_S', 'O'],
    
                     ['O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O', 'O', 'O'],
                     ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O', 'O'],
                     ['O', 'O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'O'],
    
                     ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'B_S', 'O', 'O'],
                     ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O'],
                     ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O']]
        print(merge_result(original_list))
    

    输出:

    [['B_S', 'O', 'O', 'O'], ['O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O'], ['O', 'O', 'O', 'O', 'O', 'B_S', 'O', 'O', 'B_S', 'O', 'O', 'O']]
    

    【讨论】:

      猜你喜欢
      • 2021-08-04
      • 1970-01-01
      • 2018-04-25
      • 2019-07-13
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      相关资源
      最近更新 更多