python中重复坐标的总和属性

时间:2018-06-27 19:25:03

标签: python python-3.x list

我正在查看坐标数据,由于某些预处理,我看到一些参数不同的重复坐标。我希望能够合并与匹配坐标对应的属性并获得简化的结果。为了阐明我的意思,这是一个示例:

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的和,因此保留一个点并对其求和。

我不确定如何执行此操作,我曾考虑过使用嵌套的for for循环的坐标zips,但不确定如何将其公式化以求和。

感谢您的帮助!

6 个答案:

答案 0 :(得分:4)

我认为维护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)

答案 1 :(得分:2)

这里的另一个选项是使用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 is its own inverse起,您可以通过以下方式获取New_XNew_YNew_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)

当然,您可以在一行中完成所有操作,但是我将其分解成几部分,以便于理解。

答案 2 :(得分:1)

您可以将(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]

答案 3 :(得分:1)

可以使用字典

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])

答案 4 :(得分:1)

尝试此列表理解:

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:]])

答案 5 :(得分:1)

在这里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]