如何在元组列表中对相交的 Shapely 几何对象进行分组
How to group intersecting Shapely geometric objects in a list of tuples
我有一份数据清单如下:
from shapely.geometry import box
data = [box(1,2,3,4), box(5,6,7,8), box(1,2,3,4)]
codes = ['A','B','C']
列表 'data' 具有以下 个元素:
A = box(1,2,3,4)
B = box(5,6,7,8)
C = box(1,2,3,4)
我必须检查一个元素是否与任何其他元素相交。如果相交,则放在一个元组中;如果不相交,他们应该放在不同的元组中。预期结果是:
result = [(A,C), (B)]
怎么做?
我试过:
results = []
for p,c in zip(data,codes):
for x in data:
if p.intersects(x): ##.intersects return true if they overlap else false
results.append(c)
print results
对于数据中的每个值,创建一个包含具有相交值的所有元素的元组。如果该列表不在列表中,则将其添加到结果列表中。
results=[]
for b in data
same_b = tuple([d for d in data if d.intersects(b)])
if not same_b in results:
results.append(same_b)
结果是一个元组列表,每个元组的所有元素都具有相同的值,即相交元素。
如果该元素已经被提取到 results
。
,您可以通过不创建元组来提高效率
请注意,对于给定的数据集,等于 ==
可以代替相交。
如果您想要代码而不是数据,请使用字典而不是变量名。 codes={'A':box(...),..}
保留映射到 A、B 和 C 的对象的字典,一组匹配的对象,如果它们不在我们的匹配集中,则只添加在我们到达新字母后没有匹配的单个元素将测试可能的组合:
from shapely.geometry import box
from itertools import combinations
codes = ["A", "B", "C"]
d = dict(zip(codes, data))
prev = codes[0]
matched, out = set(), []
for p1, p2 in combinations(codes, 2):
if d[p1].intersects(d[p2]):
out.append((p1, p2))
matched.update([p1, p2])
# when p1 is a new letter, we have tried all combs for that prev
# if prev is not in matched it did not intersect any other so
# add it as a single tuple and add to matched to avoid dupes
elif p1 != prev and prev not in matched:
out.append(tuple(prev,))
matched.add(prev)
prev = p1
# catch the last letter
if p2 not in matched:
out.append(tuple(p2,))
print(out)
[('A', 'C'), ('B',)]
from shapely.geometry import box
data = [box(1,2,3,4), box(5,6,7,8), box(1,2,3,4)]
codes = ['A','B','C']
创建字典以将您的代码映射到您的框:
d = dict(zip(codes, data))
检查所有组合:
intersecting = set()
for i, a in enumerate(codes, 1):
for b in codes[i:]:
if d[a].intersection(d[b]):
intersecting |= {a, b}
print(tuple(intersecting), tuple(set(codes)^intersecting))
# ('C', 'A') ('B',)
元组将是无序的,因为使用了集合。
我有一份数据清单如下:
from shapely.geometry import box
data = [box(1,2,3,4), box(5,6,7,8), box(1,2,3,4)]
codes = ['A','B','C']
列表 'data' 具有以下 个元素:
A = box(1,2,3,4)
B = box(5,6,7,8)
C = box(1,2,3,4)
我必须检查一个元素是否与任何其他元素相交。如果相交,则放在一个元组中;如果不相交,他们应该放在不同的元组中。预期结果是:
result = [(A,C), (B)]
怎么做?
我试过:
results = []
for p,c in zip(data,codes):
for x in data:
if p.intersects(x): ##.intersects return true if they overlap else false
results.append(c)
print results
对于数据中的每个值,创建一个包含具有相交值的所有元素的元组。如果该列表不在列表中,则将其添加到结果列表中。
results=[]
for b in data
same_b = tuple([d for d in data if d.intersects(b)])
if not same_b in results:
results.append(same_b)
结果是一个元组列表,每个元组的所有元素都具有相同的值,即相交元素。
如果该元素已经被提取到 results
。
请注意,对于给定的数据集,等于 ==
可以代替相交。
如果您想要代码而不是数据,请使用字典而不是变量名。 codes={'A':box(...),..}
保留映射到 A、B 和 C 的对象的字典,一组匹配的对象,如果它们不在我们的匹配集中,则只添加在我们到达新字母后没有匹配的单个元素将测试可能的组合:
from shapely.geometry import box
from itertools import combinations
codes = ["A", "B", "C"]
d = dict(zip(codes, data))
prev = codes[0]
matched, out = set(), []
for p1, p2 in combinations(codes, 2):
if d[p1].intersects(d[p2]):
out.append((p1, p2))
matched.update([p1, p2])
# when p1 is a new letter, we have tried all combs for that prev
# if prev is not in matched it did not intersect any other so
# add it as a single tuple and add to matched to avoid dupes
elif p1 != prev and prev not in matched:
out.append(tuple(prev,))
matched.add(prev)
prev = p1
# catch the last letter
if p2 not in matched:
out.append(tuple(p2,))
print(out)
[('A', 'C'), ('B',)]
from shapely.geometry import box
data = [box(1,2,3,4), box(5,6,7,8), box(1,2,3,4)]
codes = ['A','B','C']
创建字典以将您的代码映射到您的框:
d = dict(zip(codes, data))
检查所有组合:
intersecting = set()
for i, a in enumerate(codes, 1):
for b in codes[i:]:
if d[a].intersection(d[b]):
intersecting |= {a, b}
print(tuple(intersecting), tuple(set(codes)^intersecting))
# ('C', 'A') ('B',)
元组将是无序的,因为使用了集合。