python - 如何聚合嵌套列表中的元素
问题描述
我有一个列表如下:
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']]
如果您能帮助我更正我的代码,我将不胜感激!
解决方案
问题中最难的部分只是将您的列表分为三个块:
>>> [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
]
推荐阅读
- python - 有没有办法在有或没有 api 的情况下检查流媒体是否在 twitch 上直播?
- c++ - C++11 new way for Iterating through vectors?
- python - 通过两个 python 集合的不同元素过滤列表
- android - LiveDataReactiveStreams.fromPublisher crash application when not internet connection
- azure - Azure Logic 应用程序查询应用程序见解返回代码而不是 html
- python - python程序使用文件控制来监控文件
- python - 抓取文件的href后如何下载文件,其中没有http或https
- json - Why is JSON being detected as empty?
- swift - 如何快速无损地缩放 UIImages?
- c# - 为 EF Where() 子句动态构建表达式树