#!/usr/bin/env python
# coding: utf-8

# In[1]:


import pandas as pd
from tqdm import tqdm
import os
#先分训练集和测试集
folder_path = "/home/lxm/1vs1/total"  # 替换为你的文件夹路径
# # 获取文件夹中的所有文件
file_list = os.listdir(folder_path)
data_train=pd.DataFrame()
data_test=pd.DataFrame()
count=0
for file_name in tqdm(file_list, desc="Processing files"):
    if file_name.endswith(".csv"):
        count+=1
        if count<=4:
            file_path = os.path.join(folder_path, file_name)
            # 解析CSV文件
            df = pd.read_csv(file_path)  # 读取csv文件到dataframe中
            data =df.iloc[:,1:] 
            data1=pd.DataFrame(data,columns=['tar_x','tar_y','tar_z','tarEli','position_change','v','v_change','r','eli_change',
                                            'h_change','id'])
            data_train = pd.concat([data_train, data1], axis=0, ignore_index=True)  # 将文件内容合并到data_all中
#             print("train",file_path)
        else:
            file_path = os.path.join(folder_path, file_name)
            # 解析CSV文件
            df = pd.read_csv(file_path)  # 读取csv文件到dataframe中
            data =df.iloc[:,1:] 
            data1=pd.DataFrame(data,columns=['tar_x','tar_y','tar_z','tarEli','position_change','v','v_change','r','eli_change',
                                            'h_change','id'])
            data_test = pd.concat([data_test, data1], axis=0, ignore_index=True)  # 将文件内容合并到data_all中
#             print("test",file_path)
data_train.shape,data_test.shape



# In[2]:


import numpy as np
#分别在测试集和训练集中分x和y
def create_dataset(dataset,window,offset,predict_length):
    dataX, dataY = [], []
    for i in range(0,len(dataset)-window-1,offset):
        if (i + window+predict_length)<len(dataset) :
            id1=dataset[i,-1]
            id2=dataset[i+window-1,-1]
            id3=dataset[i+window+predict_length-1,-1]
            if id1==id2 and id1==id3:
                a = dataset[i:(i+window),:-1]
                dataX.append(a)
                dataY.append(dataset[i + window:(i + window+predict_length),0:3])
    return np.array(dataX), np.array(dataY)
def create_dataset1(dataset,window,offset,predict_length):
    dataX, dataY = [], []
    for i in range(0,len(dataset)-window-1,offset):
        if (i + window+predict_length)<len(dataset) :
            id1=dataset[i,-1]
            id2=dataset[i+window-1,-1]
            id3=dataset[i+window+predict_length-1,-1]
            if id1==id2 and id1==id3:
                a = dataset[i:(i+window),:-1]
                dataX.append(a)
                dataY.append(dataset[i + window:(i + window+predict_length),:-1])
    return np.array(dataX), np.array(dataY)
def create_dataset2(dataset,window,offset,predict_length):
    dataX, dataY = [], []
    placeholder=[]
    for i in range(0,len(dataset)-window-1,offset):
        if (i + window+predict_length)<len(dataset) :
            id1=dataset[i,-1]
            id2=dataset[i+window-1,-1]
            id3=dataset[i+window+predict_length-1,-1]
            if id1==id2 and id1==id3:
                a = dataset[i:(i+window),0:3]
                dataX.append(a)
                dataY.append(dataset[i + window:(i + window+predict_length),0:3])
                placeholder.append(dataset[i + window:(i + window+predict_length),3:])
    return np.array(dataX), np.array(dataY),np.array(placeholder)

train=data_train.values
test=data_test.values
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(train) ## 生成规则
data_tr = scaler.transform(train) ## 将规则应用于训练集
data_te = scaler.transform(test) ## 将规则应用于测试集
data_tr,data_te

train_X,train_Y=create_dataset(data_tr,200,100,100)
test_X,test_Y=create_dataset(data_te,200,100,100)

train_X1,train_Y1=create_dataset1(data_tr,200,100,100)
test_X1,test_Y1=create_dataset1(data_te,200,100,100)

train_X2,train_Y2,p=create_dataset2(data_tr,200,100,100)
test_X2,test_Y2,placeholder=create_dataset2(data_te,200,100,100)

train_X2.shape,train_Y2.shape,test_X2.shape,test_Y2.shape


# In[69]:


from keras.models import load_model
# load model from single file
model1 = load_model('/home/lxm/model/lstm_model3.h5')

yhat = model1.predict(test_X)



# In[132]:


from numpy import concatenate
from numpy import sqrt
from sklearn.metrics import mean_squared_error,mean_absolute_error

def reverse(yhat,test_X,test_Y):
    temp = test_X.reshape(test_X.shape[0]*test_X.shape[1], test_X.shape[2])
    temp=temp[:373700,2:]
    iny_yhat=yhat.reshape(yhat.shape[0]*yhat.shape[1],yhat.shape[2])
    #预测数据逆缩放 invert scaling for forecast
    iny = concatenate((iny_yhat, temp), axis=1)
    inverse_y = scaler.inverse_transform(iny)
    inv_y = inverse_y[:, 0:3]
    # inv_yhat = np.array(inv_yhat)
    inv_y_reshape=inv_y.reshape(int(inv_y.shape[0]/100),100,3)
    inv_y_reshape.shape
    #真实数据
    tempy=test_Y.reshape(test_Y.shape[0]*test_Y.shape[1], test_Y.shape[2])
    iny_temp= concatenate((tempy, temp), axis=1)#水平方向合并，为了适配scaler
    iny_temp1=scaler.inverse_transform(iny_temp)
    iny_real=iny_temp1[:,0:3]
    iny_real_reshape=iny_real.reshape(int(iny_real.shape[0]/100),100,3)
    iny_real_reshape
    # # # calculate RMSE
    mae = sqrt(mean_absolute_error(iny_real,inv_y))
    print('Test mae: %.3f' % mae)
    return inv_y_reshape,iny_real_reshape

inv_y_reshape,iny_real_reshape=reverse(yhat,test_X,test_Y)


# In[3]:


#连续预测
from numpy import concatenate
from numpy import sqrt
from sklearn.metrics import mean_squared_error,mean_absolute_error
from keras.models import load_model
model=load_model('/home/lxm/model/lstm_model4.h5')
model2 = load_model('/home/lxm/model/lstm_model_compare1.h5')
predict=model.predict(test_X1)
# predict.shape
predict2=model2.predict(test_X2)
predict2.shape


# In[4]:


def reverse2(predict,test_X1,test_Y1,text_X):
    temp = test_X.reshape(test_X.shape[0]*test_X.shape[1], test_X.shape[2])
    length=len(predict)
    temp1=temp[:length*100,2:]
    temp2=temp[:3737*100,2:]
    iny_yhat=predict.reshape(predict.shape[0]*predict.shape[1],predict.shape[2])
    print(iny_yhat.shape)
    print(temp1.shape)
    #预测数据逆缩放 invert scaling for forecast
    iny = concatenate((iny_yhat, temp1), axis=1)
    inverse_y = scaler.inverse_transform(iny)
    inv_y = inverse_y[:, 0:3]
    # inv_yhat = np.array(inv_yhat)
    inv_y_reshape=inv_y.reshape(length,100,3)
    inv_y_reshape.shape
    #真实数据
    tempy=test_Y.reshape(test_Y.shape[0]*test_Y.shape[1], test_Y.shape[2])
    iny_temp= concatenate((tempy, temp2), axis=1)
    iny_temp1=scaler.inverse_transform(iny_temp)
    iny_real=iny_temp1[:(length)*100,0:3]
    iny_real_reshape=iny_real.reshape(length,100,3)
    print(iny_real_reshape.shape)
    # # # calculate RMSE
    mae = sqrt(mean_absolute_error(iny_real,inv_y))
    print('Test MAE: %.3f' % mae)
    return inv_y_reshape,iny_real_reshape
    
inv_y_reshape3,iny_real_reshape3=reverse2(predict2,test_X2,test_Y2,test_X)


# In[87]:


from numpy import concatenate
from numpy import sqrt
from sklearn.metrics import mean_squared_error,mean_absolute_error

temp = test_X1.reshape(test_X1.shape[0]*test_X1.shape[1], test_X1.shape[2])
temp1=temp[:373700,-1:]
temp2=temp[:373700,2:]
iny_yhat=predict.reshape(predict.shape[0]*predict.shape[1],predict.shape[2])
#预测数据逆缩放 invert scaling for forecast
iny = concatenate((iny_yhat, temp1), axis=1)
iny.shape
inverse_y = scaler.inverse_transform(iny)
inv_y = inverse_y[:, 0:3]
# inv_yhat = np.array(inv_yhat)
inv_y_reshape=inv_y.reshape(int(inv_y.shape[0]/100),100,3)
inv_y_reshape.shape
#真实数据
tempy=test_Y1.reshape(test_Y1.shape[0]*test_Y1.shape[1], test_Y1.shape[2])
iny_temp= concatenate((tempy, temp1), axis=1)#水平方向合并，为了适配scaler
iny_temp1=scaler.inverse_transform(iny_temp)
iny_real=iny_temp1[:,0:3]
iny_real_reshape=iny_real.reshape(int(iny_real.shape[0]/100),100,3)
iny_real_reshape
# # # calculate RMSE
mae = sqrt(mean_absolute_error(iny_real,inv_y))
print('Test mae: %.3f' % mae)


# In[8]:


def predict_continuous(test_X):
    test_tr=test_X[0:1]

    # p=model.predict(test_tr)
    # p.shape
    tr=[]
    split_tr=np.vsplit(test_tr[0], 2)
    # split_tr[1].shape
    tr.append(split_tr[1])
    num=5 #连续预测次数
    for i in range(num):
        predict_y=model.predict(test_tr)
        tr.append(predict_y[0])  
        temp=tr[-2]
        test_tr=np.vstack((temp,predict_y[0]))
        test_tr=np.array([test_tr])

    tr=np.array(tr[1:])
    return tr
def predict_continuous_compare(test_X):
    test_tr=test_X[0:1]

    # p=model.predict(test_tr)
    # p.shape
    tr=[]
    split_tr=np.vsplit(test_tr[0], 2)
    # split_tr[1].shape
    tr.append(split_tr[1])
    num=5 #连续预测次数
    for i in range(num):
        predict_y=model2.predict(test_tr)
        tr.append(predict_y[0])  
        temp=tr[-2]
        test_tr=np.vstack((temp,predict_y[0]))
        test_tr=np.array([test_tr])

    tr=np.array(tr[1:])
    return tr
tr=predict_continuous(test_X1)
tr1=predict_continuous_compare(test_X2)


# In[9]:


from numpy import concatenate
from numpy import sqrt
from sklearn.metrics import mean_squared_error,mean_absolute_error

def reverse1(predict,test_X,test_Y):
    temp = test_X1.reshape(test_X.shape[0]*test_X.shape[1], test_X.shape[2])
    length=len(predict)
    temp1=temp[:length*100,-1:]
    temp2=temp[:3737*100,-1:]
    iny_yhat=predict.reshape(predict.shape[0]*predict.shape[1],predict.shape[2])
    #预测数据逆缩放 invert scaling for forecast
    iny = concatenate((iny_yhat, temp1), axis=1)
    iny.shape
    inverse_y = scaler.inverse_transform(iny)
    inv_y = inverse_y[:, 0:3]
    # inv_yhat = np.array(inv_yhat)
    inv_y_reshape=inv_y.reshape(length,100,3)
    print(inv_y_reshape.shape)
    #真实数据
    tempy=test_Y1.reshape(test_Y.shape[0]*test_Y.shape[1], test_Y.shape[2])
#     print(tempy.shape)
    iny_temp= concatenate((tempy, temp2), axis=1)#水平方向合并，为了适配scaler
    iny_temp1=scaler.inverse_transform(iny_temp)
    iny_real=iny_temp1[:(length)*100,0:3]
    iny_real_reshape=iny_real.reshape(length,100,3)
    print(iny_real_reshape.shape)
    # # # calculate RMSE
    mae = sqrt(mean_absolute_error(iny_real,inv_y))
    print('Test mae: %.3f' % mae)
    return inv_y_reshape,iny_real_reshape

inv_y_reshape1,iny_real_reshape1=reverse1(tr,test_X1,test_Y1)
inv_y_reshape4,iny_real_reshape4=reverse2(tr1,test_X2,test_Y2,test_X)
# inv_y_reshape2,iny_real_reshape2=reverse1(predict,test_X1,test_Y1)
# inv_y_reshape,iny_real_reshape=reverse(predict,test_X1,test_Y1)


# In[197]:


import matplotlib.pyplot as plt
def draw(inv_y_reshape,iny_real_reshape):
    #画出真实数据和预测数据
    predict_x,predict_y,predict_z=[],[],[]
    predict_x2,predict_y2,predict_z2=[],[],[]
    true_x,true_y,true_z=[],[],[]
    for k in range(5):
        for i in range(len(inv_y_reshape[k])):
            predict_x.append(inv_y_reshape[k][i][0])
            predict_y.append(inv_y_reshape[k][i][1])
            predict_z.append(inv_y_reshape[k][i][2])
            true_x.append(iny_real_reshape[k][i][0])
            true_y.append(iny_real_reshape[k][i][1])
            true_z.append(iny_real_reshape[k][i][2])
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.scatter(predict_x, predict_y, predict_z, s=2,label='prediction')
    ax.scatter(true_x, true_y, true_z, s=2,label='true')
    plt.legend()
    plt.show()


# In[198]:


draw(inv_y_reshape1,iny_real_reshape1)


# In[13]:


# In[202]:


draw(inv_y_reshape4,iny_real_reshape4)


# In[ ]:




