Сумма атрибутов дубликатов координат в питоне - PullRequest
0 голосов
/ 27 июня 2018

Я просматриваю свои координаты и вижу некоторые дубликаты координат с различными параметрами из-за определенной предварительной обработки. Я хочу иметь возможность объединять атрибуты, соответствующие согласованным координатам, и получать упрощенные результаты. Чтобы уточнить, что я имею в виду, вот пример:

X = [1.0, 2.0, 3.0, 2.0]
Y = [8.0, 3.0, 4.0, 3.0]
A = [13, 16, 20, 8]

Приведенные выше данные читаются следующим образом: точка (1.0, 8.0) имеет значение 13, а (2.0, 3.0) - значение 16. Обратите внимание, что вторая точка и четвертая точка имеют одинаковые координаты, но разные значения атрибута. , Я хочу иметь возможность удалять дубликаты из списков координат и суммировать атрибуты, чтобы в результате были получены новые списки:

New_X = [1.0, 2.0, 3.0]
New_Y = [8.0, 3.0, 4.0]
New_A = [13, 24, 20]

24 - это сумма 16 и 8 от второй и четвертой точек с одинаковыми координатами, поэтому сохраняется одна точка и значения суммируются.

Я не уверен, как это сделать, я подумал об использовании вложенных для циклов zips координат, но я не уверен, как его сформулировать для суммирования атрибутов.

Любая помощь приветствуется!

Ответы [ 6 ]

0 голосов
/ 27 июня 2018

A dict выглядит здесь как более подходящая структура данных. Это создаст один.

from collections import Counter

D = sum((Counter({(x, y): a}) for x, y, a in zip(X, Y, A)), Counter())
print(D)
#Counter({(2.0, 3.0): 24, (3.0, 4.0): 20, (1.0, 8.0): 13})

Вы можете распаковать их обратно в отдельные списки, используя:

New_X, New_Y, New_A = map(list, zip(*[(x,y,a) for (x,y),a in D.items()]))
print(New_X)
print(New_Y)
print(New_A)
#[1.0, 2.0, 3.0]
#[8.0, 3.0, 4.0]
#[13, 24, 20]
0 голосов
/ 27 июня 2018

Другой вариант здесь - использовать itertools.groupby. Но так как это группирует только последовательные ключи, вам сначала нужно отсортировать координаты.

Сначала мы можем zip их вместе создать кортежи вида (x, y, a). Затем отсортируйте их по (x, y) координатам:

sc = sorted(zip(X, Y, A), key=lambda P: (P[0], P[1]))  # sorted coordinates
print(sc)
#[(1.0, 8.0, 13), (2.0, 3.0, 16), (2.0, 3.0, 8), (3.0, 4.0, 20)]

Теперь мы можем groupby координаты и суммировать значения:

from itertools import groupby
print([(*a, sum(c[2] for c in b)) for a, b in groupby(sc, key=lambda P: (P[0], P[1]))])
#[(1.0, 8.0, 13), (2.0, 3.0, 24), (3.0, 4.0, 20)]

И поскольку zip является его собственным обратным , вы можете получить New_X, New_Y и New_A через:

New_X, New_Y, New_A = zip(
    *((*a, sum(c[2] for c in b)) for a, b in groupby(sc, key=lambda P: (P[0], P[1])))
)
print(New_X)
print(New_Y)
print(New_A)
#(1.0, 2.0, 3.0)
#(8.0, 3.0, 4.0)
#(13, 24, 20)

Конечно, вы можете сделать все это в одной строке, но я разбил его на части, чтобы было легче понять.

0 голосов
/ 27 июня 2018

Попробуйте этот список понимания:

y,x,a=zip(*[e for c,e in enumerate(zip(Y,X,A)) if not e[0:1] in [x[0:1] for x in zip(X,Y,A)][c:]])
0 голосов
/ 27 июня 2018

Можно использовать словарь

d = {}

for i in range(len(X)):
    tup = (X[i], Y[i])
    if tup in d:
        d[tup] += A[i]
    else:
        d[tup] = A[i]

New_X = []
New_Y = []
New_A = [] 
for key in d.keys():
    New_X.append(key[0])
    New_Y.append(key[1])
    New_A.append(d[key])
0 голосов
/ 27 июня 2018

Я думаю, что поддерживать 3 списка немного неудобно. Что-то вроде:

D = dict()
for x,y,a in zip(X,Y,A):
    D[(x,y)] = D.get((x,y),0) + a

собрал бы все вместе в одном месте.

Если вы предпочитаете разбить его обратно на 3 списка:

for (x,y),a in D.items():
    newX.append(x)
    newY.append(y)
    newA.append(a)
0 голосов
/ 27 июня 2018

вы можете поместить (x,y) координаты в словарь:

dict = {}
for i in range(len(X)) # len(X) = len(Y)
    if (X[i], Y[i]) not in dict.keys():
        dict[(X[i], Y[i])] = A[i]
    else:
       dict[(X[i], Y[i])] += A[i]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...