数组Numpy副作用

时间:2016-01-26 00:11:53

标签: numpy

用numpy替换数组时发现了一个奇怪的效果:

    def permute(yy, kmax) :
     kmax=5
     kk= np.random.uniform(1,kmax)
     nn= int(np.floor(len(yy)/kk))
     yy3= np.zeros_like(yy ); 
     np.copyto(yy3,yy)

     for ii in range(0, nn): 
        ax= kk*ii-kk*nn
        aux= yy[ax]
        aux2= yy[kk*ii] 
        yy3[ax] = aux
        yy3[kk*ii] = aux2     

     return yy3

   yy= np.random.normal(0,1,50000)
   yy1= permute(yy,2)
   ( np.var(yy)- np.var(yy1) )

   ( np.mean(yy)- np.mean(yy1) )

结果不是零!!!

你认为这是来自数组中的引用赋值吗?

1 个答案:

答案 0 :(得分:1)

我用np.arange(10)运行了你的函数并得到了

1752:~/mypy$ python stack35004877.py 
0.0
0.0
[0 1 2 3 4 5 6 7 8 9]  # yy
[0 1 2 3 4 5 6 7 8 9]  # yy1

用大型随机数组重复它,统计数字为0。

请注意,您的代码未置换输入

如果我清理它可能会更清楚:

def permute(yy, kmax=5) :
     kk= np.random.randint(1,kmax)  # int rather than float
     nn= int(np.floor(len(yy)/kk))
     print(nn,kk)
     yy3= yy.copy()
     for ii in range(0, nn):
        ind1 = kk*ii
        ind2 = ind1-kk*nn
        yy3[ind2] = yy[ind2]
        yy3[ind1] = yy[ind1]    
     return yy3

你不动了什么;使用kmax=2,您只需将yy中的所有内容复制到yy3 - 您已经在循环外执行了操作。使用kmax=5,您不会复制循环中的所有内容 - 但初始副本会隐藏该内容。

使用random.uniform()kk是一个浮点数,索引也是浮点数。这不可取,但显然不是问题。

但即使我切换索引:

    yy3[ind2] = yy[ind1]
    yy3[ind1] = yy[ind2]

我不会置换任何内容,因为ind2为负值,会映射到与ind1相同的元素。 yy[-1]yy的最后一项。

[(0, -10), (1, -9), (2, -8),... (9, -1)]

我可以弄清楚细节,但我认为你应该自己做 - 用一个小的测试用例。并跳过那个只隐藏迭代错误的初始copyto。打印详细信息,而不仅仅是来自大型随机数组的摘要统计信息。

从长远来看,你不想使用这样的迭代。您希望通过一个索引调用来进行排列。但首先让这个版本正常工作。