我的輸入資料是
mylist = [[[1820, 57, 1920, 237], [2, 3, 3]], [[1830, 90, 1920, 240], [2, 3, 4]], [[1450, 0, 1667, 197], [1, 3, 6]], [[1835, 90, 1920, 240], [0, 5, 7]],[[1452, 0, 1667, 197], [9, 9, 9]]]
我有一組矩形資料,第一個子串列包含其坐標,第二個子串列包含 rgb 資料。如果它們重疊,我想將第二個子串列分組。下面是檢查矩形是否重疊的代碼。
def isRectangleOverlap(self, R1, R2):
if (R1[0] >= R2[2]) or (R1[2] <= R2[0]) or (R1[3] <= R2[1]) or (R1[1] >= R2[3]):
return False
else:
return True
我有以下代碼:
for i in range(len(mylist)):
for j in range(i 1, len(mylist)):
if isRectangleOverlap(mylist[i][0], mylist[j][0]):
....
如果他們通過條件,第二個子串列將被組合在一起。
我的預期輸出:
[[[2, 3, 3], [2, 3, 4], [0, 5, 7]], [[1, 3, 6], [9, 9, 9]]]
你有什么建議嗎?
uj5u.com熱心網友回復:
將找到的專案設定為空串列的簡單版本。這不是很有效,因為要比較的串列不會變短。
import copy
mylist = [[[1820, 57, 1920, 237], [2, 3, 3]], [[1830, 90, 1920, 240], [2, 3, 4]], [[1450, 0, 1667, 197], [1, 3, 6]], [[1835, 90, 1920, 240], [0, 5, 7]],[[1452, 0, 1667, 197], [9, 9, 9]]]
def isRectangleOverlap(R1, R2):
if (not R1) or (not R2):
return False
if (R1[0] >= R2[2]) or (R1[2] <= R2[0]) or (R1[3] <= R2[1]) or (R1[1] >= R2[3]):
return False
else:
return True
mylist2 = copy.deepcopy(mylist)
grouped = []
for i in range(len(mylist)):
grouped.append([])
for j in range(i 1, len(mylist)):
if isRectangleOverlap(mylist[i][0], mylist2[j][0]):
if not grouped[i]: # include the i'th sublist
grouped[i].append(mylist[i][1])
grouped[i].append(mylist[j][1])
mylist2[j] = [[], []]
grouped = [sublst for sublst in grouped if sublst]
print(grouped)
一種更復雜的方法,從串列中洗掉專案,因此它不會再次檢查它們:
mylist2 = copy.deepcopy(mylist)
grouped = []
for i in range(len(mylist)):
grouped.append([])
inds_2_remove = []
for j in range(len(mylist2)):
if mylist[i] == mylist2[j]:
inds_2_remove.append(j)
continue
if isRectangleOverlap(mylist[i][0], mylist2[j][0]):
if not grouped[i]:
grouped[i].append(mylist[i][1])
grouped[i].append(mylist2[j][1])
inds_2_remove.append(j)
for ind_2_remove in reversed(inds_2_remove):
print(ind_2_remove)
del mylist2[ind_2_remove]
grouped = [sublst for sublst in grouped if sublst]
print(grouped)
uj5u.com熱心網友回復:
那是你要的嗎?我基本上做了一個嵌套的 for 回圈來構造一組集合,然后組合在一起并使用集合操作洗掉重復項。
def do_rectangles_overlap(R1, R2):
return (
False
if (R1[0] >= R2[2]) or (R1[2] <= R2[0]) or (R1[3] <= R2[1]) or (R1[1] >= R2[3])
else True
)
mylist = [
[[1820, 57, 1920, 237], [2, 3, 3]],
[[1830, 90, 1920, 240], [2, 3, 4]],
[[1450, 0, 1667, 197], [1, 3, 6]],
[[1835, 90, 1920, 240], [0, 5, 7]],
[[1452, 0, 1667, 197], [9, 9, 9]],
]
# Construct a set of sets
total_lists = set()
for i, _ in enumerate(mylist):
temp_list = set()
for j, _ in enumerate(mylist):
if do_rectangles_overlap(mylist[i][0], mylist[j][0]):
temp_list.add(tuple(mylist[i][1]))
temp_list.add(tuple(mylist[j][1]))
if temp_list:
total_lists.add(tuple(temp_list))
total_lists = {frozenset(x) for x in total_lists if len(x) != 1}
# Remove duplicate subsets from the set
m = max(map(len,total_lists))
m = {x for x in total_lists if len(x) == m}
deduplicated = set()
for j in total_lists:
if not all([j.issubset(i) for i in m]):
deduplicated.add(j)
result = m.union(deduplicated)
# Return a list
result = [tuple(x) for x in result]
print(result)
輸出:
[((1, 3, 6), (9, 9, 9)),
((0, 5, 7), (2, 3, 3), (2, 3, 4))]
uj5u.com熱心網友回復:
這是一個有趣的問題,因為有幾個曲線球。一方面,您不是在尋找重疊的矩形,而是在尋找矩形簇。您想要的結果暗示了這一點。我試圖在下面的代碼中明確表示:
mylist = [[[1820, 57, 1920, 237], [2, 3, 3]], [[1830, 90, 1920, 240], [2, 3, 4]], [[1450, 0, 1667, 197], [1, 3, 6]], [[1835, 90, 1920, 240], [0, 5, 7]],[[1452, 0, 1667, 197], [9, 9, 9]]]
# R= [Ly, Lx, Ry, Rx] = (LowerLeft-Y, LowerLeft-X, UpperRight-Y, UpperRight-X)
clusters = {}
#will hold end results, clustering overlapping rectangels together by key in mylist
#{
# 1: [1,2]
#}
def isRectangleOverlap(R1: list, R2: list):
if (R1[0] >= R2[2]) or (R1[2] <= R2[0]) or (R1[3] <= R2[1]) or (R1[1] >= R2[3]):
return False
else:
return True
def hasAlreadyOverlapped(key: int):
for k, v in clusters.items():
if key in v:
return k
return None
#itterate over every set of Rectangle,RGB combination
for i in range(len(mylist)):
cur_rect = mylist[i][0]
current_cluster = None
#check if current rectangle has already overlapped with previous rectangles,
#and if so, any new overlappings with current rectangle will be added to that cluster
#otherwise a new cluster will be created with current index i
current_cluster = hasAlreadyOverlapped(i) or i 1
#if this is a new cluster, then initiate it with current rectange in it
if not (current_cluster in clusters):
clusters[current_cluster] = [i]
#check remaining rectangles in mylist for overlapping, and add them to current cluster
#unless of course, if this is the last item.
if i < len(mylist)-1:
for j in range(i 1, len(mylist)):
if isRectangleOverlap(cur_rect, mylist[j][0]):
#this rectangle could already overlapped with a previouws processed rectangle, so we
#need to check for that.
if not (j in clusters[current_cluster]):
clusters[current_cluster].append(j)
print(clusters)
#> {1: [0, 1, 3], 3: [2, 4]}
result = []
for _, rectangles in clusters.items():
c = []
for i in rectangles:
c.append(mylist[i][1])
result.append(c)
print(result)
#> [[[2, 3, 3], [2, 3, 4], [0, 5, 7]], [[1, 3, 6], [9, 9, 9]]]
請注意,這里有一個我沒有考慮的問題。假設 rect0 和 rect8 重疊,而 rect3 和 rect4 重疊。上面的代碼將創建集群。但是,如果兩個簇都與 rect9 重疊(rect9 在 rect8 和 rect3 上延伸)怎么辦?
今天晚些時候我會有另一個想法,有趣的問題!
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/452113.html
標籤:Python 数组 python-3.x 列表
