Python 旋转阵列-然后对其进行操作
我试图创建一个数组,它是(101101),数组中每个数字的值由它与中心的距离给出 到目前为止,我已经在阵列的“顶级季度”中成功实现了这一点。我找到了一种旋转阵列的方法,这种方法同样有效。但我想做的是,旋转数组,然后对其应用相同的代码,以在下一个“象限”上获得所需的效果Python 旋转阵列-然后对其进行操作,python,arrays,Python,Arrays,我试图创建一个数组,它是(101101),数组中每个数字的值由它与中心的距离给出 到目前为止,我已经在阵列的“顶级季度”中成功实现了这一点。我找到了一种旋转阵列的方法,这种方法同样有效。但我想做的是,旋转数组,然后对其应用相同的代码,以在下一个“象限”上获得所需的效果 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
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])
从pylab导入*
关闭()
z=1((101101),dtype=integer)
a=0
b=0
c=100
d=50
当a时,问题是通过像这样旋转数组x=zip(*z[:-1])
你将numpy.array
变成一个常规的Python列表
,对于那些你不能使用元组索引的数组,比如z[a,b:c]=d
与其旋转数组,然后再次填充相同的四分之一,为什么不在同一个循环中填充所有的四分之一呢?您只需翻转阵列中的范围
此外,我还将此设置为for
循环,以使事情变得更简单。试试这个:
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 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]))
或者一次完成整个阵列块,从外到内工作:
for d in range(50, 0, -1):
a = 50 - d
b = 51 + d
z[a:b, a:b] = d
我在下面的答案中添加了一个强化的。更一般的答案和答案。稍后,在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
补遗和注意事项
如果您需要重复使用上述代码和/或使用较大的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倍 另外,g
未定义,因为第二个循环从未运行,因为您从未重置a
、b
、c
和d
我不确定如何实现您的第一个注释,当我尝试重置a、b、c的值时,我得到一个错误,告诉我第27行的列表索引必须是整数而不是元组(x[a,b:c]=d),谢谢!我将用这两种方法进行试验。很高兴知道旋转产生的是列表而不是数组。@Jacobadtr注意,在我的循环中有一些逐个错误。我现在就修好了。我注意到了,我自己也修好了:)谢谢你的帮助。这很酷——更准确地表示了距离中心像素的距离。
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]:
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]: