我正在尝试创建一个数组(101,101),数组中每个数字的值由它与中心的距离给出。
到目前为止,我已经成功地在顶级季度工作了#39;我的阵列我找到了一种旋转我的数组的方法,它也有效。但我想要做的是旋转数组,然后将相同的代码应用于它,以便在下一个象限上获得所需的效果。
from pylab import *
close()
z=ones((101,101),dtype=integer)
a=0
b=0
c=100
d=50
while a<=100 and b<=100 and c>=0 and d<=50:
z[a,b:c]=d
a=a+1
b=b+1
c=c-1
d=d-1
x=zip(*z[::-1])
当我将相同的代码应用到我的新阵列&#39; x&#39;时,我无法做任何事情。
from pylab import *
close()
z=ones((101,101),dtype=integer)
a=0
b=0
c=100
d=50
while a<=100 and b<=100 and c>=0 and d<=50:
z[a,b:c]=d
a=a+1
b=b+1
c=c-1
d=d-1
x=zip(*z[::-1])
x=zip(*z[::-1])
while a<=100 and b<=100 and c>=0 and d<=50:
x[a,b:c]=d
a=a+1
b=b+1
c=c-1
d=d-1
g=zip(*x[::,-1])
imshow(g)
show()
这只是告诉我g没有定义,但它看起来应该对我有用......请有人可以告诉我出了什么问题吗?
谢谢!
答案 0 :(得分:1)
问题在于,通过像x = zip(*z[::-1])
那样旋转数组,您将numpy.array
转换为常规Python list
,对于那些不能使用像{{1}这样的元组索引的人}}
不是旋转阵列然后再填充同一个季度,为什么不在同一个循环中填写所有区域?你只需要翻转数组中的范围。
另外,我将这个z[a,b:c] = d
循环变得更容易。试试这个:
for
或者,如果你想保持你的旋转&#34;方法,确保将旋转的数组转回实际的z = ones((101, 101), dtype=integer)
for d in range(51):
a = 50 - d
b = 50 + d
z[a, a:b+1] = d
z[b, a:b+1] = d
z[a:b+1, a] = d
z[a:b+1, b] = d
imshow(z)
show()
。同样,我建议使用两个numpy.array
循环。
for
或者一次性填写阵列的整个块,从外面开始工作:
for i in range(4):
for d in range(51):
a = 50 - d
b = 50 + d
z[a, a:b] = d
z = array(zip(*z[::-1]))
答案 1 :(得分:1)
我在下面的答案中加了一个补强。更一般的答案和。之后,对numpy
我有一个功能,只有在n
为奇数时它才有效但在n
为奇数时它可以正常工作...
def radius(n):
if (n+1)%2 : return None
a = np.zeros((n,n))
for r in range(n/2,n):
x = r - n/2
for c in range(n/2,n):
y = c-n/2
a[r,c] = np.sqrt(x*x+y*y)
a[n/2-1::-1,n/2:] = a[n/2+1:,n/2:]
a[:,n/2-1::-1] = a[:,n/2+1:]
return a
请注意,这可能不是最理想的,因为您可能需要计算一次n/2
并重复使用以下十倍的值...
这只是更好,特别是对于n
的偶数值也可以正常工作。
def radius(n):
import numpy as np
if n<1 : return
if n == 1 : return np.zeros((1,1))
a = np.zeros((n,n))
hn = n/2
C = float(n-1)/2.0
for r in range(hn,n):
y2= (r-C)**2
for c in range(hn,n):
x2 = (c-C)**2
a[r,c] = np.sqrt(y2+x2)
if n%2:
a[hn-1::-1,hn:] = a[hn+1:,hn:]
a[:,hn-1::-1] = a[:,hn+1:]
else:
a[hn-1::-1,hn:] = a[hn:,hn:]
a[:,hn-1::-1] = a[:,hn:]
return a
(这只是对版本1的测试,对不起,但我还测试了版本2 ...)
In [1]: import numpy as np
In [2]: def radius(n):
if (n+1)%2 : return None
a = np.zeros((n,n))
for r in range(n/2,n):
x = r - n/2
for c in range(n/2,n):
y = c-n/2
a[r,c] = np.sqrt(x*x+y*y)
a[n/2-1::-1,n/2:] = a[n/2+1:,n/2:]
a[:,n/2-1::-1] = a[:,n/2+1:]
return a
...:
In [3]: np.set_printoptions(linewidth=120, precision=2)
In [4]: radius(14)
In [5]: radius(15)
Out[5]:
array([[ 9.9 , 9.22, 8.6 , 8.06, 7.62, 7.28, 7.07, 7. , 7.07, 7.28, 7.62, 8.06, 8.6 , 9.22, 9.9 ],
[ 9.22, 8.49, 7.81, 7.21, 6.71, 6.32, 6.08, 6. , 6.08, 6.32, 6.71, 7.21, 7.81, 8.49, 9.22],
[ 8.6 , 7.81, 7.07, 6.4 , 5.83, 5.39, 5.1 , 5. , 5.1 , 5.39, 5.83, 6.4 , 7.07, 7.81, 8.6 ],
[ 8.06, 7.21, 6.4 , 5.66, 5. , 4.47, 4.12, 4. , 4.12, 4.47, 5. , 5.66, 6.4 , 7.21, 8.06],
[ 7.62, 6.71, 5.83, 5. , 4.24, 3.61, 3.16, 3. , 3.16, 3.61, 4.24, 5. , 5.83, 6.71, 7.62],
[ 7.28, 6.32, 5.39, 4.47, 3.61, 2.83, 2.24, 2. , 2.24, 2.83, 3.61, 4.47, 5.39, 6.32, 7.28],
[ 7.07, 6.08, 5.1 , 4.12, 3.16, 2.24, 1.41, 1. , 1.41, 2.24, 3.16, 4.12, 5.1 , 6.08, 7.07],
[ 7. , 6. , 5. , 4. , 3. , 2. , 1. , 0. , 1. , 2. , 3. , 4. , 5. , 6. , 7. ],
[ 7.07, 6.08, 5.1 , 4.12, 3.16, 2.24, 1.41, 1. , 1.41, 2.24, 3.16, 4.12, 5.1 , 6.08, 7.07],
[ 7.28, 6.32, 5.39, 4.47, 3.61, 2.83, 2.24, 2. , 2.24, 2.83, 3.61, 4.47, 5.39, 6.32, 7.28],
[ 7.62, 6.71, 5.83, 5. , 4.24, 3.61, 3.16, 3. , 3.16, 3.61, 4.24, 5. , 5.83, 6.71, 7.62],
[ 8.06, 7.21, 6.4 , 5.66, 5. , 4.47, 4.12, 4. , 4.12, 4.47, 5. , 5.66, 6.4 , 7.21, 8.06],
[ 8.6 , 7.81, 7.07, 6.4 , 5.83, 5.39, 5.1 , 5. , 5.1 , 5.39, 5.83, 6.4 , 7.07, 7.81, 8.6 ],
[ 9.22, 8.49, 7.81, 7.21, 6.71, 6.32, 6.08, 6. , 6.08, 6.32, 6.71, 7.21, 7.81, 8.49, 9.22],
[ 9.9 , 9.22, 8.6 , 8.06, 7.62, 7.28, 7.07, 7. , 7.07, 7.28, 7.62, 8.06, 8.6 , 9.22, 9.9 ]])
In [6]:
如果您需要重复使用上面的代码和/或n
的大值,请查看以下时间并将双循环更改为numpy可以向量化的内容...
In [71]: def do(n):
a = np.zeros((n,n))
for r in range(n):
y2 = r*r
for c in range(n):
a[r,c] = np.sqrt(y2+c*c)
return a
....:
In [72]: do(7)
Out[72]:
array([[ 0. , 1. , 2. , 3. , 4. , 5. , 6. ],
[ 1. , 1.41, 2.24, 3.16, 4.12, 5.1 , 6.08],
[ 2. , 2.24, 2.83, 3.61, 4.47, 5.39, 6.32],
[ 3. , 3.16, 3.61, 4.24, 5. , 5.83, 6.71],
[ 4. , 4.12, 4.47, 5. , 5.66, 6.4 , 7.21],
[ 5. , 5.1 , 5.39, 5.83, 6.4 , 7.07, 7.81],
[ 6. , 6.08, 6.32, 6.71, 7.21, 7.81, 8.49]])
In [73]: n = 7 ; a = np.arange(n) ; o = np.ones(n) ; np.sqrt(np.outer(o,a*a)+np.outer(a*a,o))
Out[73]:
array([[ 0. , 1. , 2. , 3. , 4. , 5. , 6. ],
[ 1. , 1.41, 2.24, 3.16, 4.12, 5.1 , 6.08],
[ 2. , 2.24, 2.83, 3.61, 4.47, 5.39, 6.32],
[ 3. , 3.16, 3.61, 4.24, 5. , 5.83, 6.71],
[ 4. , 4.12, 4.47, 5. , 5.66, 6.4 , 7.21],
[ 5. , 5.1 , 5.39, 5.83, 6.4 , 7.07, 7.81],
[ 6. , 6.08, 6.32, 6.71, 7.21, 7.81, 8.49]])
In [74]: %timeit do(1001)
1 loops, best of 3: 2.45 s per loop
In [75]: %timeit n = 1001 ; a = np.arange(n) ; o = np.ones(n) ; np.sqrt(np.outer(o,a*a)+np.outer(a*a,o))
100 loops, best of 3: 13.2 ms per loop
In [76]:
正如您所看到的,非矢量化代码(如我的示例代码中所示)几乎比矢量化版本慢200倍!