我有一个函数可以根据给定的边界框创建网格。我最近遇到一种情况,在某些条件下,
zip
调用最终返回的数字远低于输入的预期排列。
考虑以下 MWE:
import numpy as np
def makegrid(xmin, ymin, xmax, ymax):
xmin = int(np.floor(xmin / 1000) * 1000)
ymin = int(np.floor(ymin / 1000) * 1000)
xmax = int(np.ceil(xmax / 1000) * 1000)
ymax = int(np.ceil(ymax / 1000) * 1000)
left_list = [ left for bottom in range(ymin, ymax, 1000) for left in range(xmin, xmax, 1000) ]
bottom_list = [ bottom for left in range(xmin, xmax, 1000) for bottom in range(ymin, ymax, 1000) ]
right_list = [left + 1000 for left in left_list]
top_list = [bottom + 1000 for bottom in bottom_list]
#edit - add print statement showing input dims
print(f"dims: {len(left_list)}, {len(bottom_list)}, {len(right_list)}, {len(top_list)}")
zip_coords = zip(left_list,bottom_list,right_list,top_list)
zcoords = list(zip_coords)
print(f"expecting: {len(set(left_list)) * len(set(bottom_list))} tiles")
print(f"produced: {len(set(zcoords))} tiles")
#example one - works correctly
makegrid(452958.56 , 3684771.695, 551076.93 , 3846044.225)
#expecting: 16300
#produced: 16300
#example two - does not work and produces a fraction of expected
makegrid(518249.995, 3630269.23 , 638616.78 , 3816623.475)
#expecting: 22627
#produced: 2057
#example three - add some jitter to example two, back to working correctly
makegrid(518249.995, 3640269.23 , 640616.78 , 3856623.475)
#expecting: 26691
#produced: 26691
#example four - a different jitter, does not match
makegrid(519249.995, 3630169.23 , 638516.78 , 3812623.475)
#expecting: 21960
#produced: 7320
我已经验证每个输入列表的大小相同。我还尝试在 zip 调用中添加
strict=True
参数,但我无法弄清楚为什么 zip 函数会将条目向下折叠。
你的函数太复杂了。您想要的只是两个范围的笛卡尔积;为此,请使用
itertools.product
,而不是将两个多重集压缩在一起。
def makegrid(xmin, ymin, xmax, ymax):
xmin = int(np.floor(xmin / 1000) * 1000)
ymin = int(np.floor(ymin / 1000) * 1000)
xmax = int(np.ceil(xmax / 1000) * 1000)
ymax = int(np.ceil(ymax / 1000) * 1000)
x_coords = range(xmin, xmax, 1000)
y_coords = range(ymin, ymax, 1000)
return list(product(x_coords, y_coords))
您还可以直接使用列表理解:
return [(x, y) for x in x_coords for y in y_coords]