这里提供两种不同的数据划分方式,看喜好选择了鸭
第一种数据划分的方式
pandas的shift()函数
import pandas as pd
df = pd.DataFrame()
df["time"] = [x for x in range(10)]
df
df["time-1"] = df["time"].shift(1)
df
| time | time-1 |
---|
0 | 0 | NaN |
---|
1 | 1 | 0.0 |
---|
2 | 2 | 1.0 |
---|
3 | 3 | 2.0 |
---|
4 | 4 | 3.0 |
---|
5 | 5 | 4.0 |
---|
6 | 6 | 5.0 |
---|
7 | 7 | 6.0 |
---|
8 | 8 | 7.0 |
---|
9 | 9 | 8.0 |
---|
df["time+1"] = df["time"].shift(-1)
df
| time | time-1 | time+1 |
---|
0 | 0 | NaN | 1.0 |
---|
1 | 1 | 0.0 | 2.0 |
---|
2 | 2 | 1.0 | 3.0 |
---|
3 | 3 | 2.0 | 4.0 |
---|
4 | 4 | 3.0 | 5.0 |
---|
5 | 5 | 4.0 | 6.0 |
---|
6 | 6 | 5.0 | 7.0 |
---|
7 | 7 | 6.0 | 8.0 |
---|
8 | 8 | 7.0 | 9.0 |
---|
9 | 9 | 8.0 | NaN |
---|
df["time+2"] = df["time"].shift(-2)
df
| time | time-1 | time+1 | time+2 |
---|
0 | 0 | NaN | 1.0 | 2.0 |
---|
1 | 1 | 0.0 | 2.0 | 3.0 |
---|
2 | 2 | 1.0 | 3.0 | 4.0 |
---|
3 | 3 | 2.0 | 4.0 | 5.0 |
---|
4 | 4 | 3.0 | 5.0 | 6.0 |
---|
5 | 5 | 4.0 | 6.0 | 7.0 |
---|
6 | 6 | 5.0 | 7.0 | 8.0 |
---|
7 | 7 | 6.0 | 8.0 | 9.0 |
---|
8 | 8 | 7.0 | 9.0 | NaN |
---|
9 | 9 | 8.0 | NaN | NaN |
---|
在时间序列预测问题中, 当前时间t和未来时间(t+1,t+n)被称为预测时间,过去的观测值(t-1,t-n)是用于预测的
新的数据集被构造为Dataframe,每列根据变量的编号以及该列左移或者右移的步长命名
def series_to_supervisied(data,step_in,step_out,dropnan = True):
"""
param:data观测序列,类型为列表或者二维的numpy数组
param:step_in:作为输入滞后观测值数量(x)
param:step_out:作为输出的观测值为(y)
param:dropnan:是否删除具有NaN的行,称为bool,默认为True
return:为监督学习重组得到的dataframe序列
"""
n_vars = 1 if type(data) is list else data.shape[1]
df = pd.DataFrame(data)
cols,names = [],[]
for i in range(step_in,0,-1):
cols.append(df.shift(i))
names+=[("var%d(t-%d)"%(j+1,i)) for j in range(n_vars)]
for i in range(0,step_out):
cols.append(df.shift(-i))
names+=[("var%d(t+%d)"%(j+1,i)) for j in range(n_vars)]
agg = pd.concat(cols,axis=1)
agg.columns = names
if dropnan:
agg.dropna(inplace=True)
return agg
values = [x for x in range(10)]
data = series_to_supervisied(data=values,step_in=1,step_out=1)
data
| var1(t-1) | var1(t+0) |
---|
1 | 0.0 | 1 |
---|
2 | 1.0 | 2 |
---|
3 | 2.0 | 3 |
---|
4 | 3.0 | 4 |
---|
5 | 4.0 | 5 |
---|
6 | 5.0 | 6 |
---|
7 | 6.0 | 7 |
---|
8 | 7.0 | 8 |
---|
9 | 8.0 | 9 |
---|
def series_to_supervisied_(data,step_in,step_out,dropnan = True):
"""
param:data观测序列,类型为列表或者二维的numpy数组
param:step_in:作为输入滞后观测值数量(x)
param:step_out:作为输出的观测值为(y)
param:dropnan:是否删除具有NaN的行,称为bool,默认为True
return:为监督学习重组得到的dataframe序列
"""
n_vars = 1 if type(data) is list else data.shape[1]
df = pd.DataFrame()
df_time_in =pd.DataFrame()
df_time_out = pd.DataFrame()
df["time"] =data
for i in range(step_in,0,-1):
name = "step_"+"time-"+str(i)
print(name)
df_time_in[name] = df["time"].shift(i)
print(name)
for i in range(1,step_out+1):
name = "step_"+"time+"+str(i)
print(name)
df_time_out[name] = df["time"].shift(-i)
print(name)
df_re = pd.concat([df_time_in,df,df_time_out],axis =1)
del df,df_time_in,df_time_out
if dropnan:
df_re.dropna(inplace=True)
return df_re
values = [x for x in range(10)]
data = series_to_supervisied_(data=values,step_in=3,step_out=0)
data
step_time-3
step_time-3
step_time-2
step_time-2
step_time-1
step_time-1
| step_time-3 | step_time-2 | step_time-1 | time |
---|
3 | 0.0 | 1.0 | 2.0 | 3 |
---|
4 | 1.0 | 2.0 | 3.0 | 4 |
---|
5 | 2.0 | 3.0 | 4.0 | 5 |
---|
6 | 3.0 | 4.0 | 5.0 | 6 |
---|
7 | 4.0 | 5.0 | 6.0 | 7 |
---|
8 | 5.0 | 6.0 | 7.0 | 8 |
---|
9 | 6.0 | 7.0 | 8.0 | 9 |
---|
单步单变量预测
用(t-1)作为输入变量预测当前时间的观测值(t),同理,可以指定任意长度的输入
def series_to_supervisied_(data,step_in,step_out,dropnan = True):
"""
param:data观测序列,类型为列表或者二维的numpy数组
param:step_in:作为输入滞后观测值数量(x)
param:step_out:作为输出的观测值为(y)
param:dropnan:是否删除具有NaN的行,称为bool,默认为True
return:为监督学习重组得到的dataframe序列
"""
n_vars = 1 if type(data) is list else data.shape[1]
df = pd.DataFrame()
df_time_in =pd.DataFrame()
df_time_out = pd.DataFrame()
df["time"] =data
for i in range(step_in,0,-1):
name = "step_"+"time-"+str(i)
df_time_in[name] = df["time"].shift(i)
for i in range(0,step_out):
name = "step_"+"time+"+str(i)
df_time_out[name] = df["time"].shift(-i)
df_re = pd.concat([df_time_in,df_time_out],axis =1)
del df,df_time_in,df_time_out
if dropnan:
df_re.dropna(inplace=True)
return df_re
values = [x for x in range(10)]
data = series_to_supervisied_(data=values,step_in=1,step_out=1)
data
| step_time-1 | step_time+0 |
---|
1 | 0.0 | 1 |
---|
2 | 1.0 | 2 |
---|
3 | 2.0 | 3 |
---|
4 | 3.0 | 4 |
---|
5 | 4.0 | 5 |
---|
6 | 5.0 | 6 |
---|
7 | 6.0 | 7 |
---|
8 | 7.0 | 8 |
---|
9 | 8.0 | 9 |
---|
def series_to_supervisied_(data,step_in,step_out,dropnan = True):
"""
param:data观测序列,类型为列表或者二维的numpy数组
param:step_in:作为输入滞后观测值数量(x)
param:step_out:作为输出的观测值为(y)
param:dropnan:是否删除具有NaN的行,称为bool,默认为True
return:为监督学习重组得到的dataframe序列
"""
n_vars = 1 if type(data) is list else data.shape[1]
df = pd.DataFrame()
df_time_in =pd.DataFrame()
df_time_out = pd.DataFrame()
df["time"] =data
for i in range(step_in,0,-1):
name = "step_"+"time-"+str(i)
df_time_in[name] = df["time"].shift(i)
for i in range(0,step_out):
name = "step_"+"time+"+str(i)
df_time_out[name] = df["time"].shift(-i)
df_re = pd.concat([df_time_in,df_time_out],axis =1)
del df,df_time_in,df_time_out
if dropnan:
df_re.dropna(inplace=True)
return df_re
values = [x for x in range(10)]
data = series_to_supervisied_(data=values,step_in=2,step_out=1)
data
| step_time-2 | step_time-1 | step_time+0 |
---|
2 | 0.0 | 1.0 | 2 |
---|
3 | 1.0 | 2.0 | 3 |
---|
4 | 2.0 | 3.0 | 4 |
---|
5 | 3.0 | 4.0 | 5 |
---|
6 | 4.0 | 5.0 | 6 |
---|
7 | 5.0 | 6.0 | 7 |
---|
8 | 6.0 | 7.0 | 8 |
---|
9 | 7.0 | 8.0 | 9 |
---|
多步预测
def series_to_supervisied_(data,step_in,step_out,dropnan = True):
"""
param:data观测序列,类型为列表或者二维的numpy数组
param:step_in:作为输入滞后观测值数量(x)
param:step_out:作为输出的观测值为(y)
param:dropnan:是否删除具有NaN的行,称为bool,默认为True
return:为监督学习重组得到的dataframe序列
"""
n_vars = 1 if type(data) is list else data.shape[1]
df = pd.DataFrame()
df_time_in =pd.DataFrame()
df_time_out = pd.DataFrame()
df["time"] =data
for i in range(step_in,0,-1):
name = "step_"+"time-"+str(i)
df_time_in[name] = df["time"].shift(i)
for i in range(0,step_out):
name = "step_"+"time+"+str(i)
df_time_out[name] = df["time"].shift(-i)
df_re = pd.concat([df_time_in,df_time_out],axis =1)
del df,df_time_in,df_time_out
if dropnan:
df_re.dropna(inplace=True)
return df_re
values = [x for x in range(10)]
data = series_to_supervisied_(data=values,step_in=2,step_out=2)
data
| step_time-2 | step_time-1 | step_time+0 | step_time+1 |
---|
2 | 0.0 | 1.0 | 2 | 3.0 |
---|
3 | 1.0 | 2.0 | 3 | 4.0 |
---|
4 | 2.0 | 3.0 | 4 | 5.0 |
---|
5 | 3.0 | 4.0 | 5 | 6.0 |
---|
6 | 4.0 | 5.0 | 6 | 7.0 |
---|
7 | 5.0 | 6.0 | 7 | 8.0 |
---|
8 | 6.0 | 7.0 | 8 | 9.0 |
---|
多变量预测
def series_to_superivsed(data,step_in =1,step_out=1,dropnan = True):
"""
param:data观测序列,类型为列表或者二维的numpy数组
param:step_in:作为输入滞后观测值数量(x)
param:step_out:作为输出的观测值为(y)
param:dropnan:是否删除具有NaN的行,称为bool,默认为True
return:为监督学习重组得到的dataframe序列
"""
n_vars = 1 if type(data) is list else data.shape[1]
df = pd.DataFrame(data)
cols = []
names = []
for i in range(step_in,0,-1):
cols.append(df.shift(i))
names+=[("var%d(t-%d)"%(j+1,i)) for j in range(n_vars)]
for i in range(0,step_out):
cols.append(df.shift(-i))
if i ==0:
names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
else:
names+=[("var%d(t+%d)"%(j+1,i)) for j in range(n_vars)]
df_re = pd.concat(cols,axis=1)
df_re.columns = names
if dropnan:
df_re.dropna(inplace =True)
return df_re
raw = pd.DataFrame()
raw['ob1'] = [x for x in range(10)]
raw['ob2'] = [x for x in range(50, 60)]
values = raw.values
data = series_to_superivsed(values)
data
| var1(t-1) | var2(t-1) | var1(t) | var2(t) |
---|
1 | 0.0 | 50.0 | 1 | 51 |
---|
2 | 1.0 | 51.0 | 2 | 52 |
---|
3 | 2.0 | 52.0 | 3 | 53 |
---|
4 | 3.0 | 53.0 | 4 | 54 |
---|
5 | 4.0 | 54.0 | 5 | 55 |
---|
6 | 5.0 | 55.0 | 6 | 56 |
---|
7 | 6.0 | 56.0 | 7 | 57 |
---|
8 | 7.0 | 57.0 | 8 | 58 |
---|
9 | 8.0 | 58.0 | 9 | 59 |
---|
raw['ob1'] = [x for x in range(10)]
raw['ob2'] = [x for x in range(50, 60)]
values = raw.values
data = series_to_superivsed(values,1,2)
data
| var1(t-1) | var2(t-1) | var1(t) | var2(t) | var1(t+1) | var2(t+1) |
---|
1 | 0.0 | 50.0 | 1 | 51 | 2.0 | 52.0 |
---|
2 | 1.0 | 51.0 | 2 | 52 | 3.0 | 53.0 |
---|
3 | 2.0 | 52.0 | 3 | 53 | 4.0 | 54.0 |
---|
4 | 3.0 | 53.0 | 4 | 54 | 5.0 | 55.0 |
---|
5 | 4.0 | 54.0 | 5 | 55 | 6.0 | 56.0 |
---|
6 | 5.0 | 55.0 | 6 | 56 | 7.0 | 57.0 |
---|
7 | 6.0 | 56.0 | 7 | 57 | 8.0 | 58.0 |
---|
8 | 7.0 | 57.0 | 8 | 58 | 9.0 | 59.0 |
---|
第二种数据划分的方式
索引 | 数据 |
---|
0 | 10 |
1 | 20 |
2 | 30 |
3 | 40 |
4 | 50 |
5 | 60 |
6 | 70 |
7 | 80 |
8 | 90 |
9 | 100 |
10 | 110 |
假如time_step(3)个步长预测一个样本 ,得到如下表
索引 | x | y |
---|
0 | 10,20,30 | 40 |
1 | 20,30,40 | 50 |
2 | 30,40,50 | 60 |
3 | 40,50,60 | 70 |
4 | 50,60,70 | 80 |
5 | 60,70,80 | 90 |
6 | 70,80,90 | 100 |
7 | 80,90,100 | 110 |
8 | 90,100,110 | ? |
9 | 100,110,? | ?? |
10 | 110,?,?? | ??? |
import numpy as np
def split_sequence(sequence,n_steps):
x,y = [],[]
for i in range(len(sequence)):
end_idx = i+n_steps
if end_idx>len(sequence)-1:
break
input_x,input_y = sequence[i:end_idx],sequence[end_idx]
x.append(input_x)
y.append(input_y)
return np.array(x),np.array(y)
raw_seq = [10,20,30,40,50,60,70,80,90]
n_steps = 3
x,y = split_sequence(raw_seq,n_steps)
for i in range(len(x)):
print(x[i],y[i])
[10 20 30] 40
[20 30 40] 50
[30 40 50] 60
[40 50 60] 70
[50 60 70] 80
[60 70 80] 90
多变量时间序列是指每个时间步长有一个观测值的数据
多个输入的系列·
索引 | x1,x2 | y |
---|
0 | 10,15 | 25 |
1 | 20,25 | 45 |
2 | 30,35 | 65 |
3 | 40,45 | 85 |
4 | 50,55 | 105 |
5 | 60,65 | 125 |
6 | 70,75 | 145 |
7 | 80,85 | 165 |
8 | 90,95 | 185 |
in_seq1 =np. array([10, 20, 30, 40, 50, 60, 70, 80, 90])
in_seq2 = np.array([15, 25, 35, 45, 55, 65, 75, 85, 95])
out_seq = np.array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))])
array([ 25, 45, 65, 85, 105, 125, 145, 165, 185])
in_seq1 = in_seq1.reshape((len(in_seq1), 1))
in_seq2 = in_seq2.reshape((len(in_seq2), 1))
out_seq = out_seq.reshape((len(out_seq), 1))
data = np.hstack((in_seq1,in_seq2,out_seq))
data
array([[ 10, 15, 25],
[ 20, 25, 45],
[ 30, 35, 65],
[ 40, 45, 85],
[ 50, 55, 105],
[ 60, 65, 125],
[ 70, 75, 145],
[ 80, 85, 165],
[ 90, 95, 185]])
索引 | x1,x2 | y |
---|
0 | 10,15 | |
1 | 20,25 | |
2 | 30,35 | 65 |
3 | 20,25 | |
4 | 30,35 | |
5 | 40,45 | 85 |
6 | … | … |
def split_sequence(sequence,n_steps):
x,y = [],[]
for i in range(len(sequence)):
end_idx = i+n_steps
if end_idx>len(sequence):
break
input_x,input_y = sequence[i:end_idx,:-1],sequence[end_idx-1,-1]
x.append(input_x)
y.append(input_y)
return np.array(x),np.array(y)
n_steps = 3
x,y = split_sequence(data,n_steps)
for i in range(len(x)):
print(x[i], y[i])
print("="*15)
[[10 15]
[20 25]
[30 35]] 65
===============
[[20 25]
[30 35]
[40 45]] 85
===============
[[30 35]
[40 45]
[50 55]] 105
===============
[[40 45]
[50 55]
[60 65]] 125
===============
[[50 55]
[60 65]
[70 75]] 145
===============
[[60 65]
[70 75]
[80 85]] 165
===============
[[70 75]
[80 85]
[90 95]] 185
===============
多个序列输出
索引 | x1,x2 | y |
---|
0 | 10,15 | 25 |
1 | 20,25 | 45 |
2 | 30,35 | 65 |
3 | 40,45 | 85 |
4 | 50,55 | 105 |
5 | 60,65 | 125 |
6 | 70,75 | 145 |
7 | 80,85 | 165 |
8 | 90,95 | 185 |
索引 | x1,x2 | y |
---|
0 | 10,15 | 25 |
1 | 20,25 | 45 |
2 | 30,35 | 65 |
输出 | | |
3 | 40,45 | 85 |
def split_sequence(sequences,n_step):
x,y = [],[]
for i in range(len(sequences)):
end_idx = i+n_step
if end_idx>len(sequences)-1:
break
input_x,input_y = sequences[i:end_idx,:],sequences[end_idx,:]
x.append(input_x)
y.append(input_y)
return np.array(x),np.array(y)
in_seq1 = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90])
in_seq2 = np.array([15, 25, 35, 45, 55, 65, 75, 85, 95])
out_seq = np.array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))])
in_seq1 = in_seq1.reshape((len(in_seq1), 1))
in_seq2 = in_seq2.reshape((len(in_seq2), 1))
out_seq = out_seq.reshape((len(out_seq), 1))
data =np. hstack((in_seq1, in_seq2, out_seq))
n_steps = 3
x,y = split_sequence(data,n_steps)
for i in range(len(x)):
print(x[i], y[i])
print("="*20)
[[10 15 25]
[20 25 45]
[30 35 65]] [40 45 85]
====================
[[20 25 45]
[30 35 65]
[40 45 85]] [ 50 55 105]
====================
[[ 30 35 65]
[ 40 45 85]
[ 50 55 105]] [ 60 65 125]
====================
[[ 40 45 85]
[ 50 55 105]
[ 60 65 125]] [ 70 75 145]
====================
[[ 50 55 105]
[ 60 65 125]
[ 70 75 145]] [ 80 85 165]
====================
[[ 60 65 125]
[ 70 75 145]
[ 80 85 165]] [ 90 95 185]
====================
多个输入,多个输出
索引 | 数据 |
---|
0 | 10 |
1 | 20 |
2 | 30 |
3 | 40 |
4 | 50 |
5 | 60 |
6 | 70 |
7 | 80 |
8 | 90 |
9 | 100 |
10 | 110 |
def split_sequence(sequence,n_steps_in,n_steps_out):
x,y =[],[]
for i in range(len(sequence)):
end_idx = i+n_steps_in
out_end_idx = end_idx + n_steps_out
if out_end_idx>len(sequence):
break
input_x,input_y = sequence[i:end_idx],sequence[end_idx:out_end_idx]
x.append(input_x)
y.append(input_y)
return np.array(x),np.array(y)
raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90]
n_steps_in, n_steps_out = 3, 2
x, y = split_sequence(raw_seq, n_steps_in, n_steps_out)
for i in range(len(x)):
print(x[i], y[i])
print("="*20)
[10 20 30] [40 50]
====================
[20 30 40] [50 60]
====================
[30 40 50] [60 70]
====================
[40 50 60] [70 80]
====================
[50 60 70] [80 90]
====================
多个维度的输入输出
索引 | x1,x2 | y |
---|
0 | 10,15 | 25 |
1 | 20,25 | 45 |
2 | 30,35 | 65 |
3 | 40,45 | 85 |
4 | 50,55 | 105 |
5 | 60,65 | 125 |
6 | 70,75 | 145 |
7 | 80,85 | 165 |
8 | 90,95 | 185 |
索引 | x1,x2 | y |
---|
0 | 10,15 | |
1 | 20,25 | |
2 | 30,35 | |
输出 | | |
3 | | 65 |
4 | | 85 |
def split_sequence(sequences,n_steps_in,n_steps_out):
x,y = [],[]
for i in range(len(sequences)):
end_idx = i+n_steps_in
out_end_idx = end_idx+n_steps_out-1
if out_end_idx>len(sequences):
break
input_x,input_y = sequences[i:end_idx,:-1],sequences[end_idx-1:out_end_idx,-1]
x.append(input_x)
y.append(input_y)
return np.array(x),np.array(y)
in_seq1 = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90])
in_seq2 = np.array([15, 25, 35, 45, 55, 65, 75, 85, 95])
out_seq = np.array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))])
in_seq1 = in_seq1.reshape((len(in_seq1), 1))
in_seq2 = in_seq2.reshape((len(in_seq2), 1))
out_seq = out_seq.reshape((len(out_seq), 1))
data = np.hstack((in_seq1, in_seq2, out_seq))
n_steps_in, n_steps_out = 3, 2
x, y = split_sequence(data, n_steps_in, n_steps_out)
for i in range(len(x)):
print(x[i], y[i])
print("="*30)
[[10 15]
[20 25]
[30 35]] [65 85]
==============================
[[20 25]
[30 35]
[40 45]] [ 85 105]
==============================
[[30 35]
[40 45]
[50 55]] [105 125]
==============================
[[40 45]
[50 55]
[60 65]] [125 145]
==============================
[[50 55]
[60 65]
[70 75]] [145 165]
==============================
[[60 65]
[70 75]
[80 85]] [165 185]
==============================
索引 | x1,x2 | y |
---|
0 | 10,15 | 25 |
1 | 20,25 | 45 |
2 | 30,35 | 65 |
3 | 40,45 | 85 |
4 | 50,55 | 105 |
5 | 60,65 | 125 |
6 | 70,75 | 145 |
7 | 80,85 | 165 |
8 | 90,95 | 185 |
索引 | x1,x2 | y |
---|
0 | 10,15 | 25 |
1 | 20,25 | 45 |
2 | 30,35 | 65 |
3 | 40,45 | 85 |
输出 | | |
4 | 50,55 | 105 |
5 | 60,65 | 125 |
def split_sequences(sequences,n_steps_in,n_steps_out):
x,y = [],[]
for i in range(len(sequences)):
end_idx = i+n_steps_in
out_end_idx = end_idx+n_steps_out
if out_end_idx>len(sequences):
break
input_x,input_y = sequences[i:end_idx,:],sequences[end_idx:out_end_idx,:]
x.append(input_x)
y.append(input_y)
return np.array(x),np.array(y)
in_seq1 = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90])
in_seq2 = np.array([15, 25, 35, 45, 55, 65, 75, 85, 95])
out_seq = np.array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))])
in_seq1 = in_seq1.reshape((len(in_seq1), 1))
in_seq2 = in_seq2.reshape((len(in_seq2), 1))
out_seq = out_seq.reshape((len(out_seq), 1))
dataset = np.hstack((in_seq1, in_seq2, out_seq))
n_steps_in, n_steps_out = 3, 2
X, y = split_sequences(dataset, n_steps_in, n_steps_out)
for i in range(len(X)):
print(X[i], y[i])
print("="*30)
[[10 15 25]
[20 25 45]
[30 35 65]] [[ 40 45 85]
[ 50 55 105]]
==============================
[[20 25 45]
[30 35 65]
[40 45 85]] [[ 50 55 105]
[ 60 65 125]]
==============================
[[ 30 35 65]
[ 40 45 85]
[ 50 55 105]] [[ 60 65 125]
[ 70 75 145]]
==============================
[[ 40 45 85]
[ 50 55 105]
[ 60 65 125]] [[ 70 75 145]
[ 80 85 165]]
==============================
[[ 50 55 105]
[ 60 65 125]
[ 70 75 145]] [[ 80 85 165]
[ 90 95 185]]
==============================