import  numpy as np
import  pandas  as  pd
import matplotlib.pyplot  as  plt
from sklearn.preprocessing import StandardScaler

data=pd.read_csv("C:/Users/Administrator/Desktop/factor_of_data.csv")
print(data)
pd.set_option('display.max_rows',None)



x = data.as_matrix()
print(x)
#x=np.array([[1,2,3],[4,5,6],[7,8,9]])
#y = data['target']

#标准化数据集
x_stand =StandardScaler().fit_transform(x)
#x_stand=np.array([[1,2,3],[4,5,6],[7,8,9]])

#协方差矩阵
mean_vector=np.mean(x_stand,axis=0)
cov_matrix=((x_stand-mean_vector).T.dot(x_stand-mean_vector))/(x_stand.shape[0]-1)
cov_matrix_1=np.cov(x_stand.T)

#计算特征值和特征向量
e_values,e_vector = np.linalg.eig(cov_matrix)

print("协方差矩阵的特征值为: \n  %s"  %e_values)
print("协方差矩阵的特征向量为: \n  %s"  %e_vector)

#将特征值和特征向量合并
new_values=e_values[:,np.newaxis]
print("将特征值变成二维矩阵: \n  %s"  %new_values)
matrix_values_vector=np.hstack((e_vector,new_values))
print("合并后的矩阵有多少列: \n  %s"  %matrix_values_vector.shape[1])
print(matrix_values_vector)


#给定阈值80%,计算主成分
threshold=0.99*e_values.sum() 
print("主成分阈值为: \n  %s"  %threshold)

#定义一个函数,用来返回满足阈值的特征值和特征向量
def  return_e_values_vector(threshold,e_values,e_vector,matrix_values_vector):
    e_values_sort=-np.sort(-e_values,axis=0)#降序排列
    print("排序后的特征值 : \n  %s"  %e_values_sort)
    numbers_e_values=e_values.size#特征值的个数
    sum_values=0;
    for i  in range(numbers_e_values):
       
        values=e_values_sort[i]        
        sum_values=sum_values+values
        print(sum_values)
        
        
        if sum_values>=threshold:#判断累加数值超过阈值的那个特征向量的位置
            print(sum_values)
            threshold_e_values=e_values[0:i+1]
          
            for j  in range(i+1):
                #print("j的值: %s  \n" %j)                
                vector=matrix_values_vector[matrix_values_vector[:,(matrix_values_vector.shape[1]-1)]==threshold_e_values[j]]
                if j==0:
                    threshold_e_vector=vector
                else:
                    threshold_e_vector=np.vstack((threshold_e_vector,vector))
                
                
            print("经过阈值处理后剩下的特征值: \n %s" %threshold_e_values) 
            threshold_e_vector=threshold_e_vector[:,0:(threshold_e_vector.shape[1]-1)]
            print("经过阈值处理后剩下的特征向量: \n %s" %threshold_e_vector)
            break       
            
    return threshold_e_values,threshold_e_vector

#定义一个函数,求经过降维之后的数据值
def result(threshold_e_vector,x):
    x_result=threshold_e_vector.dot(x.T)
    
    return x_result
#main
threshold_e_values,threshold_e_vector=return_e_values_vector(threshold,e_values,e_vector,matrix_values_vector)
result=result(threshold_e_vector,x)

