2016-06-07 90 views
0

我正在写这个类来规范数组中的数据。当我使用self.x上的范数函数返回规范化的矩阵时,self.x会被覆盖。类内Python范围

不知道为什么self.x矩阵覆盖掉了:

class normData(): 

    def __init__(self, file): 
     self.file = file 
     self.data = self.readtxt() 
     self.x = self.data[:,0:-1] 
     self.y = self.data[:,-1] 
     # self.y_norm = self.norm(self.y) 
     # self.x_norm = self.norm(self.x) 

    def readtxt(self): 
     arr = [] 
     data = open(self.file, 'r') 
     for line in data.readlines(): 
      point = line.split(',') 
      arr.append([float(point[i]) for i in range(len(point))]) 
     arr = np.append(np.ones([len(arr),1]),arr,1) 
     return arr 

    def norm(self, matrix): 
     mat = matrix 
     col_num = len(mat[0]) 
     row_num = len(mat) 
     mu = np.array([np.average(mat[:,i]) for i in range(col_num)]) 
     size = np.array([max(mat[:,i])-min(mat[:,i]) for i in range(col_num)]) 
     for i in range(len(size)): 
      if (size[i] > 0.00001): 
       mat[:,i]=(mat[:,i]-mu[i])/size[i] 
     return mat 

我的猜测是可变的“垫子”被作为对象“矩阵”(self.x传入规范),在内存中,并且然后覆盖?

编辑/问题澄清:避免覆盖python类结构中现有数据的最佳方法是什么?

+1

如果在Python类结构中不起作用 –

+0

?可以使用'.copy()'或者'import deepcopy'“:该类与它无关。更多的事实是,赋值并不总是复制东西(当使用'='时,引用列表和numpy数组,而不是复制)。 – Evert

回答

3

在Python中,任何超越简单的内置类型的传递通过引用功能,这意味着功能没有得到一个对象的副本,而对象本身:

def f(x): 
    x[2] = 100 

x = [1, 2, 3, 4] 
f(x) 
print(x) 
# [1, 2, 100, 4] 

这也是赋值运算符的真实:简单地说y = xmat = matrix不会使对象的副本,而是创建了一个新的名字指向同一个对象:

x = [1, 2, 3, 4] 
y = x 
y[2] = 100 
print(x) 
# [1, 2, 100, 4] 

如果你真的想要一个numpy的阵列或任何副本其他对象,你编辑是明确的。与numpy的做到这一点的方法之一是使用.copy()方法:

x = np.arange(4) 
y = x.copy() 
y[2] = 100 
print(y) 
# [ 0 1 100 3] 
print(x) 
# [0 1 2 3] 

无论你是一个类中操作,这将举行。

+0

谢谢,有用的解释 – bpr