import numpy as np
import pandas as pd
from interval import Interval
from openpyxl import Workbook
import time
start = time.clock()
def loadDataSet(filename):
    E = pd.read_excel(filename, sheet_name=0, header=None)
    E = np.array(E)
    return E
def missing_number(a):
    c = 0
    for i in range(len(X)):
        v1 = list(a[:, 0])
        tmp_list = sorted(v1)
        c = tmp_list.count(0)   # 计算出每一列的缺失值数量
    return c

def min_max(a):
    d, b = 0, 0
    v1 = list(a[:, 0])
    tmp_list = sorted(v1)
    c = tmp_list.count(0)
    d = tmp_list[c]  # 每一列的最小值
    b = X[:, j].max()  # 每一列的最大值
    return d, b

def intervals(up,low,number):
    h = (up - low) / number
    return h

def qujian(d, t, h):
    I = np.zeros((1, t))
    u = np.zeros((1, t))
    # for s in range(t-1):
    #     I[0][s] = Interval(d + (s - 1) * h, d + s * h, lower_closed=False)
    # I[0][t] = Interval(d + (t - 1) * h, d + t * h,lower_closed=False)
    for s in range(1,t+1):
        u[0][s-1] = (d + (s - 1) * h + d + s * h) / 2
    return u

def contribution(a,t, u,  h):
    miu = np.zeros((len(X), t))
    for s in range(t):
        for i in range(len(X)):
            if a[i][0] != 0:
                if np.linalg.norm(a[i][0] - u[0][s]) <= h:
                    miu[i][s] = 1 - (np.linalg.norm(a[i][0] - u[0][s]) / h)
                else:
                    miu[i][s] = 0
            else:
                miu[i][s] = 0
    return miu

def fenjie(t, a, miu):
    m = np.zeros((len(X), t))
    for s in range(t):
        for i in range(len(X)):
            if a[i][0] != 0:
                m[i][s] = miu[i][s] * a[i][0]
    return m

def recover(t, miu,m):

    m_head = np.zeros((1, t))
    for s in range(t):
        v = 0
        n = 0
        k = 0
        o = 0
        for i in range(len(X)):
            if a[i][0] != 0:
                v = v + miu[i][s]
                o = o + m[i][s]
                n = n + a[i][0]
                k = k + 1
        if v == 0:
            m_head[0][s] = n / k
        else:
            m_head[0][s] = o / v
    return m_head

def backfill(m_head,a):
    s = 0
    for i in range(len(X)):
        if a[i][0] == 0:
            a[i][0] = m_head[0][s]
            s = s + 1
    return a


if __name__ == '__main__':
    X = loadDataSet('A(10%_33416).xlsx')  # 归一化后缺失数据集
    X_m = loadDataSet('missing_index_A(10).xlsx')
    XX1 = loadDataSet('standA.xlsx')
    number = 0
    for i in range(len(X)):
        for j in range(len(X[0])):
            if X_m[i][j] == 11:
                number += 1
    print(number)
    print(X)
    new = np.zeros((len(X), 1))
    for x in range(len(X[0])):
        # print('column',x)
        a = np.zeros((len(X), 1))
        for j in range(x, x+1):
            for i in range(len(X)):
                a[i][0] = X[i][j]
        t = missing_number(a)
        xiao, da = min_max(a)
        # print('min_max',da,xi ao)
        h = intervals(da,xiao,t)
        zhong = qujian(xiao, t, h)
        con_miu = contribution(a, t, zhong, h)
        m_combine = fenjie(t, a, con_miu)
        m_head = recover(t,con_miu,m_combine)
        a_fill = backfill(m_head,a)
        new = np.hstack((new,a_fill))
        # print('new', new,len(new),len(new[0]))
    new = np.delete(new,0,axis=1)  # 填补完的数聚集
    X_orginal = XX1
    X_estimate = new
    XXX = np.zeros((len(X_orginal),len(X_orginal[0])))
    for i in range(len(X_orginal)):
        for j in range(len(X_orginal[0])):
            if X_m[i][j] == 11: #and j != 5 and j != 4 and j != 8:
                XXX[i][j] = X_estimate[i][j]
            else:
                XXX[i][j] = X_orginal[i][j]

    QQ = X
    target = XX1
    prediction = XXX
    error = np.zeros((len(target),len(target[0])))
    for i in range(len(QQ)):
        for j in range(len(QQ[0])):
            if X_m[i][j] == 11:
                if QQ[i][j] == 0:
                    error[i][j] = target[i][j] - prediction[i][j]
                else:
                    error[i][j] = 0
    print("Errors: ", error)
    squaredError = np.zeros((len(target),len(target[0])))
    absError = np.zeros((len(target),len(target[0])))
    for i in range(len(target)):
        for j in range(len(target[0])):
            squaredError[i][j] = error[i][j] * error[i][j]
            absError[i][j] = abs(error[i][j])
    s = np.sum(squaredError)
    s_mae = np.sum(absError)
    print(s,s_mae)
    print("RMSE = ", np.sqrt(s / number))  # 均方误差MSE
    print("MSE = ", s / number)
    print("MAE = ", s_mae / number)
    book = Workbook()
    sheet = book.create_sheet('Sheet',index=0)
    [h, l] = XXX.shape
    for i in range(h):
        for j in range(l):
            sheet.cell(row=i+1, column=j+1, value=XXX[i][j])
    book.save('Fill_A(10).xlsx')  # fill完成的
end = time.clock()
t = end - start
print('Run time is :', t)







