2013-11-14 4 views
0

У меня есть список списков, таких как:(х, у) пара для максимального значения г в списке

nodes =[[nodeID,x,y,z],....] 

Я хочу найти:

xi,yi for zi=zmax given zmax= max z for same x,y 

и хранить (xi,yi,zi) в другом списке ,

Я могу сделать это с помощью:

nodes=[[literal_eval(x) for x in item] for item in nodes] 
maxz_levels=[] 
for i,row in enumerate(nodes): 
    fe=0 
    maxz=0 
    nodeID,x,y,z=row 
    for j,line in enumerate(nodes): 
     nodeID2,x2,y2,z2=line 
     if x==x2 and y==y2 and z2>maxz: 
      maxz=z2 
    if len(maxz_levels)==0: 
     maxz_levels.append([x, y, maxz]) 
    else: 
     for row2 in maxz_levels: 
      if row2[0]==x and row2[1]==y: 
       fe=1 
     if fe==0: 
      maxz_levels.append([x, y, maxz]) 

но это берет возрасты ... поэтому я думал использовать словарь, но я не найти простой способ сделать то, что я хочу. Мой код:

dic1=defaultdict(list)    
for nodeID,x,y,z in nodes: 
    dic1[(x,y)].append((nodeID,z)) 
for key in dic1: 
    dic1[key].sort(key=lambda x:float(x[1])) 
for j,row in enumerate(nodes): 
    nodeID,x,y,z=row 
    z_levels=[item[1] for item in dic1[(x,y)]] 
    #How to find easily and quickly the max of z_levels and the associated (x,y) coordinates? 

Любые идеи? Благодаря

EDIT: пример:

nodes = [['1','1','1','2'],['2','1','1','3'],['3','0','0','5'],['4','0','0','4'],['5','1','2','4'],['6','0','0','40'],['7','0','10','4'],['8','10','0','4'],['9','0','0','4'],['10','2','1','4']] 

Я хочу найти:

maxz_levels = [[1, 1, 3], [0, 0, 40], [1, 2, 4], [0, 10, 4], [10, 0, 4], [2, 1, 4]] 
+0

Вы должны инициализировать 'maxz' в первом цикле, я думаю. Он не ответит на вашу проблему, но я не уверен, что ваше текущее решение работает. –

+0

Да, вы правы! Но в моем случае это работает, потому что maxz всегда один и тот же :) – jpcgandre

ответ

1

Если вы деталь предписание X и Y, то:

from itertools import groupby 
from operator import itemgetter 

nodes = [['1','1','1','2'],['2','1','1','3'],['3','0','0','5'],['4','0','0','4']]  
result = [max(g, key=itemgetter(3))[1:] for k, g in groupby(nodes, itemgetter(1, 2))] 
# [['1', '1', '3'], ['0', '0', '5']] 

В противном случае, вы можете предоставить sorted(nodes, key=itemgetter(1, 2)) вместо nodes к groupby.

+0

Если они не сгруппированы, это не сработает. Если они все работают. Теперь мой вопрос: как сгруппировать этот список: 'nodes = [['1', '1', '1', '2'], ['2', '1', '1', '3'] , [ '3', '0', '0', '5'], [ '4', '0', '0', '4'], [ '5', '1', '2', '4'], ['6', '0', '0', '40'], ['7', '0', '10', '4'], ['8', '10' , '0', '4'], ['9', '0', '0', '4'], ['10', '2', '1', '4']] ' – jpcgandre

+1

@jpcgandre вы попробовали предложение в конце ... –

1
Вы можете использовать функцию max с ключом:
maxz = max(list_, key=lambda x: x[3])
Это присвоит maxz к вопросу о списке list_ с максимальным значением с индексом 3 (значение z). Затем вы можете извлечь `` xi` и yi` значения:
xi, yi = (maxz[1], maxz[2])

Если вы хотите, чтобы отсортировать список по nodes г, вы можете использовать функцию sorted вместе с key:
maxz_levels = sorted(nodes, key=lambda x: x[3], reverse=True) , а затем удалить первый элемент.


Хорошо, я думаю, что, наконец, у вас возник вопрос. Так вот функциональная попытка:

maxz_levels = [] 
for i in set([(i[1], i[2]) for i in nodes]): 
    m = sorted(filter(lambda x: x[1] == i[0] and x[2] == i[1], nodes))[-1] 
    maxz_levels.append((m[1], m[2], m[3])) 

Объяснение:

  • Цикл for перебирает список всех (x, y) комбинаций в nodes
  • Первая строка в цикле сортирует список всех элементов в nodes с текущими (x, y) значениями по их значению z и принимает последний (тот, который имеет наибольшее значение z).
  • Вторая строка в цикле добавляет этот узел в список максимальных узлов.
+1

Это даст вам абсолютный максимум. Результатом должен быть список (x, y, z), сгруппированный по (x, y). – Matthias

+0

Мне нужно было бы создать 'list_' в виде списка с одинаковыми координатами' x, y'. Я думаю, что мой список «z_levels» можно использовать. Я попробую. – jpcgandre

+0

Это не будет делать то, что я хочу. Если 'nodes = [['1', '1', '1', '2'], ['2', '1', '1', '3'], ['3', '0', '0', '1'], ['4', '0', '0', '4']] ', тогда я получаю' [['4', '0', '0', '4'] , ['2', '1', '1', '3'], ['1', '1', '1', '2'], ['3', '0', '0', '1']] ', но я хочу' [['0', '0', '4'], ['1', '1', '3']] '... – jpcgandre

1
#!/usr/bin/env python3 


nodes = [['1','1','1','2'],['2','1','1','3'],['3','0','0','5'],['4','0','0','4']] 

d = {} 

for z in nodes: 
    x = (z[1], z[2]) 
    if x not in d: 
     d[x] = z[3] 
    elif d[x] < z[3]: 
     d[x] = z[3] 

output = [] 
for x in d: 
    output.append(x+(d[x],)) 
print(output) 

Выход:

[('0', '0', '5'), ('1', '1', '3')] 
+0

что такое' x'? спасибо – jpcgandre

+0

@jpcgandre спасибо, что указали на ошибку. Изменили код. – shantanoo

Смежные вопросы