Python 使用Keras TimeseriesGenerator函数按某个ID生成squence组

Python 使用Keras TimeseriesGenerator函数按某个ID生成squence组,python,keras,lstm,Python,Keras,Lstm,我需要使用TimeseriesGenerator将数据馈送到LSTM网络。情况是,由TimeSeries生成器函数生成的序列需要只考虑IDS内的值。对于EG,考虑以下数据: dt = pd.DataFrame({'ids':[1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3], 'values':[1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7]}) 对于序列长度为3,我需要以下输出: [[[1., 1.], [1., 2.

我需要使用TimeseriesGenerator将数据馈送到LSTM网络。情况是,由TimeSeries生成器函数生成的序列需要只考虑IDS内的值。对于EG,考虑以下数据:

dt = pd.DataFrame({'ids':[1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3], 'values':[1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7]})
对于序列长度为3,我需要以下输出:

[[[1., 1.], [1., 2.], [1., 3.]]
,[[1., 2.], [1., 3.], [1., 4.]]
,[[1., 3.], [1., 4.], [1., 5.]]
,[[1., 4.], [1., 5.], [1., 6.]]
,[[1., 5.], [1., 6.], [1., 7.]]
,[[2., 1.], [2., 2.], [2., 3.]]
,[[2., 2.], [2., 3.], [2., 4.]]
 ...
 ]
但是,当我运行以下命令时:

X = TimeseriesGenerator(dt.values,dt.values,3,batch_size = dt.shape[0])
在ID=2的序列开始之前,我得到了以下两个额外的不需要的元素:

[[1., 6.], [1., 7.],[2., 1.]],[[1., 7.],[2., 1.],[2., 2.]]

我知道循环使用所有ID是一种解决方案,但在现实生活中这样做需要花费大量时间,有什么捷径可以实现吗?

您必须编写自定义数据生成器。下面的代码应该适合您自定义的基于ID的批处理生成,您可以将其用作基线,并根据需要对其进行调整

import keras
import numpy as np
class DataGenerator(keras.utils.Sequence):
    def __init__(self, dt, length, batch_size=128):
        self.tgs = list()
        for i in range(dt['ids'].min(),dt['ids'].max()+1):
            adf = dt[dt['ids'] == i]
            self.tgs.append(TimeseriesGenerator(adf.values,adf.values,length,batch_size =batch_size))
        self.len = sum([len(tg) for tg in self.tgs])
        self.idx_i = list()
        self.idx_j = list()

        for i, tg in enumerate(self.tgs):
            self.idx_i.extend(list(range(len(tg))))
            self.idx_j.extend([i]*len(tg))    
        #print ( self.idx_i,  self.idx_j)

    def __len__(self):
        return self.len

    def __getitem__(self, index):
        return self.tgs[self.idx_j[index]][self.idx_i[index]]

# Test
g = DataGenerator(dt,3,3)
for i in range(len(g)):
    print (g[i])
  • 我正在为每个id创建一个生成器,并将其存储在
    tgs
  • 批次数是每个生成器中批次的总和
  • idx_j
    将索引映射到相应的生成器
  • idx_i
    将索引映射到由
    idx_j
输出:

(array([[[1., 1.], [1., 2.], [1., 3.]],
        [[1., 2.], [1., 3.], [1., 4.]],
        [[1., 3.], [1., 4.], [1., 5.]]]), 
        array([[1., 4.], [1., 5.], [1., 6.]]))
(array([[[2., 1.], [2., 2.], [2., 3.]],
       [[2., 2.], [2., 3.], [2., 4.]],
       [[2., 3.], [2., 4.], [2., 5.]]]), 
       array([[2., 4.], [2., 5.], [2., 6.]]))
(array([[[3., 1.], [3., 2.],[3., 3.]],
       [[3., 2.], [3., 3.], [3., 4.]],
       [[3., 3.], [3., 4.], [3., 5.]]]), 
       array([[3., 4.], [3., 5.], [3., 6.]]))

实际上,
TimeseriesGenerator
源代码也使用循环来获取数据。如果你想节省时间,你需要重写你自己的
TimeseriesGenerator
类。其他方法只能在不节省时间的情况下减少代码。github的源代码似乎还没有满。它只有一个pass语句。您可以在此处参考
TimeseriesGenerator
源代码。