旋转阵列 - 然后操纵它

时间:2015-03-18 11:27:54

标签: python arrays

我正在尝试创建一个数组(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没有定义,但它看起来应该对我有用......请有人可以告诉我出了什么问题吗?

谢谢!

2 个答案:

答案 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]: 

Addendum et Caveat Emptor

如果您需要重复使用上面的代码和/或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倍!