将 FunctionTransformer 与 sklearn Pipeline 和 ColumnTransformer 一起使用 - 错误:无效的类型提升
Posted
技术标签:
【中文标题】将 FunctionTransformer 与 sklearn Pipeline 和 ColumnTransformer 一起使用 - 错误:无效的类型提升【英文标题】:Using FunctionTransformer with sklearn Pipeline and ColumnTransformer - error: invalid type promotion 【发布时间】:2020-01-31 18:53:21 【问题描述】:我正在使用管道来预处理数据。这是我的代码。我想将字符串列转换为日期时间,并将空字符串 (' ')、"N.A" 替换为 np.nan
用于其他一些列。我正在尝试在我的管道步骤中使用FunctionTransformer
。
df = pd.DataFrame('categoric1':['Apple', ' ', 'Cherry', 'Apple', 'Cherry', 'Cherry', 'Orange'],
'numeric1':[1, 2, 3, 4, 5, 6, 7],
'numeric2':[7,8,9,"N.A", np.nan, ' ', 12],
'date1': ['20001103','20011109', '19910929', '19920929', '20051107', '20081103', '20101105'])
cat_features = ['categoric1']
num_features = ['numeric1', 'numeric2']
date_features = ['date1']
print(df.head(7))
def replace_with_nan(X):
X_copy = X.copy()
X_copy[X_copy == ' '] = np.nan
X_copy[X_copy == 'N.A'] = np.nan
return X_copy.values
def square_values(X):
return X**2
def convert_to_datetime(df):
df['date1'] = pd.to_datetime(df['date1'], errors='raise') #df['date1'].astype(str) + "Z"
return df
cat_transformer = Pipeline(steps=[
('ft_replace_nan', FunctionTransformer(replace_with_nan, validate=False)),
('imputer', SimpleImputer(missing_values=np.nan, strategy='most_frequent')),
('encoder', OneHotEncoder(categories=[['Apple', 'Orange', 'Cherry']], handle_unknown='error'))
])
num_transformer = Pipeline(steps=[
('ft_replace_nan', FunctionTransformer(replace_with_nan, validate=False)),
# ('ft_square_values', FunctionTransformer(square_values, validate=False)), #Another FunctionTransformer -----1
('imputer', SimpleImputer(missing_values=np.nan, strategy='median')),
('scaler', StandardScaler())
])
date_transformer = Pipeline(steps=[
('convert_to_datetime', FunctionTransformer(convert_to_datetime, validate=False))
])
preprocessor = ColumnTransformer(remainder='passthrough', transformers = [
('num', num_transformer, num_features),
('cat', cat_transformer, cat_features),
('date', date_transformer, date_features)
])
# ft_fill_nan = FunctionTransformer(replace_with_nan, validate=False)
# transformed_data = ft_fill_nan.fit_transform(df)
# print(transformed_data)
# ft_convert_datetime = FunctionTransformer(convert_to_datetime, validate=False)
# transformed_data = ft_convert_datetime.fit_transform(df)
# print(transformed_data)
transformed_data = preprocessor.fit_transform(df)
print(transformed_data)
问题:
-
当我尝试执行
preprocessor.fit_transform(df)
时,我得到了
错误如下。你能帮我解决这个问题吗?
如果我想在同一管道中执行另一个 FunctionTransformer 以求平方怎么办
取消注释行 #Another FunctionTransformer -----1
的值。可能吗?如果有,怎么做?
我不想改变里面实际数据的状态
convert_to_datetime(df)
上面的方法。我还想让它通用而不访问实际的date1
列。我怎样才能做到这一点?
【问题讨论】:
【参考方案1】:-
由于异构数据类型,您收到
invalid type promotion
错误。 Sklearn 正在尝试在内部使用 numpy 结构数组进行连接。解决方案是从日期中提取必要的特征,例如给定日期的月份。
您只需要更改convert_to_datetime
def convert_to_datetime(data):
return data.apply(lambda x: [pd.to_datetime(date, format="%Y%m%d").month for date in x])
通过这种方式,您不必在函数内对列名进行硬编码。
结果:
-
您可以轻松添加更多功能转换器,试试这个!
('ft_square_values', FunctionTransformer(lambda x: x*2, validate=False)), #Another FunctionTransformer -----1
-
通过采用第 1 点中提到的解决方案,您也可以摆脱这个问题。
【讨论】:
以上是关于将 FunctionTransformer 与 sklearn Pipeline 和 ColumnTransformer 一起使用 - 错误:无效的类型提升的主要内容,如果未能解决你的问题,请参考以下文章
Sklearn 自定义转换器:使用 FunctionTransformer 和子类化 TransformerMixin 的区别
用它包装的函数保存一个 sklearn `FunctionTransformer`
继承自 SciKit FunctionTransformer