Iterate over 2d array in an expanding circular spiral(在扩展的圆形螺旋中迭代二维数组)
问题描述
给定一个 n 由 n 矩阵 M 在行 i 和列 j代码>,我想以圆形螺旋遍历所有相邻值.
Given an n by n matrix M, at row i and column j, I'd like to iterate over all the neighboring values in a circular spiral.
这样做的目的是测试一些函数,f,它依赖于 M,找到距离 (i, j) 的半径,其中 >f 返回 True.所以,f 看起来像这样:
The point of doing this is to test some function, f, which depends on M, to find the radius away from (i, j) in which f returns True. So, f looks like this:
def f(x, y):
"""do stuff with x and y, and return a bool"""
并且会这样调用:
R = numpy.zeros(M.shape, dtype=numpy.int)
# for (i, j) in M
for (radius, (cx, cy)) in circle_around(i, j):
if not f(M[i][j], M[cx][cy]):
R[cx][cy] = radius - 1
break
其中 circle_around 是返回(迭代器到)圆形螺旋中的索引的函数.因此,对于M 中的每个点,此代码将计算并存储从f 返回True 的那个点开始的半径.
Where circle_around is the function that returns (an iterator to) indices in a circular spiral. So for every point in M, this code would compute and store the radius from that point in which f returns True.
如果有更有效的计算 R 的方法,我也愿意接受.
If there's a more efficient way of computing R, I'd be open to that, too.
感谢所有提交答案的人.我编写了一个简短的函数来绘制 circle_around 迭代器的输出,以显示它们的作用.如果您更新答案或发布新答案,则可以使用此代码来验证您的解决方案.
Thanks to everyone who submitted answers. I've written a short function to plot the output from your circle_around iterators, to show what they do. If you update your answer or post a new one, you can use this code to validate your solution.
from matplotlib import pyplot as plt
def plot(g, name):
plt.axis([-10, 10, -10, 10])
ax = plt.gca()
ax.yaxis.grid(color='gray')
ax.xaxis.grid(color='gray')
X, Y = [], []
for i in xrange(100):
(r, (x, y)) = g.next()
X.append(x)
Y.append(y)
print "%d: radius %d" % (i, r)
plt.plot(X, Y, 'r-', linewidth=2.0)
plt.title(name)
plt.savefig(name + ".png")
结果如下:plot(circle_around(0, 0), "F.J"):
plot(circle_around(0, 0, 10), "WolframH"):
我将 Magnesium 的建议编码如下:
I've coded up Magnesium's suggestion as follows:
def circle_around_magnesium(x, y):
import math
theta = 0
dtheta = math.pi / 32.0
a, b = (0, 1) # are there better params to use here?
spiral = lambda theta : a + b*theta
lastX, lastY = (x, y)
while True:
r = spiral(theta)
X = r * math.cos(theta)
Y = r * math.sin(theta)
if round(X) != lastX or round(Y) != lastY:
lastX, lastY = round(X), round(Y)
yield (r, (lastX, lastY))
theta += dtheta
plot(circle_around(0, 0, 10), "magnesium"):
如您所见,满足我正在寻找的接口的结果都没有产生一个圆形螺旋,该螺旋覆盖了 0、0 附近的所有索引.FJ 是最接近的,尽管 WolframH 的命中点是正确的,只是不是按螺旋顺序.
As you can see, none of the results that satisfy the interface I'm looking for have produced a circular spiral that covers all of the indices around 0, 0. F.J's is the closest, although WolframH's hits the right points, just not in spiral order.
推荐答案
既然提到点的顺序无关紧要,我就简单的按角度排序(arctan2)它们出现在给定的半径处.更改 N 以获得更多积分.
Since it was mentioned that the order of the points do not matter, I've simply ordered them by the angle (arctan2) in which they appear at a given radius. Change N to get more points.
from numpy import *
N = 8
# Find the unique distances
X,Y = meshgrid(arange(N),arange(N))
G = sqrt(X**2+Y**2)
U = unique(G)
# Identify these coordinates
blocks = [[pair for pair in zip(*where(G==idx))] for idx in U if idx<N/2]
# Permute along the different orthogonal directions
directions = array([[1,1],[-1,1],[1,-1],[-1,-1]])
all_R = []
for b in blocks:
R = set()
for item in b:
for x in item*directions:
R.add(tuple(x))
R = array(list(R))
# Sort by angle
T = array([arctan2(*x) for x in R])
R = R[argsort(T)]
all_R.append(R)
# Display the output
from pylab import *
colors = ['r','k','b','y','g']*10
for c,R in zip(colors,all_R):
X,Y = map(list,zip(*R))
# Connect last point
X = X + [X[0],]
Y = Y + [Y[0],]
scatter(X,Y,c=c,s=150)
plot(X,Y,color=c)
axis('equal')
show()
为 N=8 提供:
更多点N=16(对不起色盲):
More points N=16 (sorry for the colorblind):
这显然接近一个圆并按半径增加的顺序击中每个网格点.
This clearly approaches a circle and hits every grid point in order of increasing radius.
这篇关于在扩展的圆形螺旋中迭代二维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在扩展的圆形螺旋中迭代二维数组
基础教程推荐
- kivy 应用程序中的一个简单网页作为小部件 2022-01-01
- 究竟什么是“容器"?在蟒蛇?(以及所有的 python 容器类型是什么?) 2022-01-01
- Python,确定字符串是否应转换为 Int 或 Float 2022-01-01
- Kivy 使用 opencv.调整图像大小 2022-01-01
- Python 中是否有任何支持将长字符串转储为块文字或折叠块的 yaml 库? 2022-01-01
- 在 Django Admin 中使用内联 OneToOneField 2022-01-01
- matplotlib 设置 yaxis 标签大小 2022-01-01
- 比较两个文本文件以找出差异并将它们输出到新的文本文件 2022-01-01
- 对多索引数据帧的列进行排序 2022-01-01
- 在 Python 中将货币解析为数字 2022-01-01
