Я решил проблему, создав преобразователь, который обрабатывает процесс конкатенации.
class append_split_3D(BaseEstimator, TransformerMixin):
def __init__(self, segments_number=20, max_len=50, mode='append'):
self.segments_number = segments_number
self.max_len = max_len
self.mode = mode
self.appending_value = -5.123
def fit(self, X, y=None):
return self
def transform(self, data):
if self.mode == 'append':
self.max_len = self.max_len - data.shape[2]
appending = np.full((data.shape[0], data.shape[1], self.max_len), self.appending_value)
new = np.concatenate([data, appending], axis=2)
return new
elif self.mode == 'split':
tmp = []
for item in range(0, data.shape[1], self.segments_number):
tmp.append(data[:, item:(item + self.segments_number), :])
tmp = [item[item != self.appending_value].reshape(data.shape[0], self.segments_number, -1) for item in tmp]
new = np.concatenate(tmp, axis=2)
return new
else:
print('Error: Mode value is not defined')
exit(1)
, где полный конвейер становится таким:
manual_feats = Pipeline([
('FeatureUnion', FeatureUnion([
('segmenting_pip1', Pipeline([
('A_features', A_features()),
('segmentation', segmentation()),
('append', append_split_3D(max_len=50, mode='append')),
])),
('segmenting_pip2', Pipeline([
('B_features', B_features(),
('segmentation', segmentation())
('append', append_split_3D(max_len=50, mode='append')),
])),
('segmenting_pip3', Pipeline([
('Z_features', Z_features()),
('segmentation', segmentation())
('append', append_split_3D(max_len=50, mode='append')),
])),
])),
('split', append_split_3D(segments_number=10, mode='split')),
])
То, что я сделал в этом преобразователе,следующее: Например, имеющаяся у меня функция A
, B
и Z
возвращает следующие массивы:
A
: (# записей, 10, 20) B
: (количество записей 10, 20) Z
: (количество записей 10, 15)
Вmode='append'
, я добавляю все массивы с дополнительными фиксированными значениями максимальной длины 50
(в качестве примера), чтобы иметь одинаковое значение axis=2
dim и позволить функции Xs = np.hstack(Xs)
работать.
Таким образом, в результате конвейер вернет массив: (# of records, 30, 50)
Затем, в mode=split'
, я добавляю его в конце конвейера, я разделяю окончательный массив на их добавленныйформа: (# of records, 30, 50)
до 3 элементов массива dim (# of records, 10, 50)
Затем я удаляю дополнительное фиксированное значение и применяю конкатенацию к последнему dim.
Dim финального массива: (# of records, 10, 55)
. 55 - объединение 3-го измерения массивов (20 + 20 + 15), что я и хочу.