用于 sklearn 管道的 pandas 到 numpy 数组
Posted
技术标签:
【中文标题】用于 sklearn 管道的 pandas 到 numpy 数组【英文标题】:pandas to numpy array for sklearn pipeline 【发布时间】:2017-03-05 11:20:35 【问题描述】:我有一个转换器,可以计算每组值的百分比。最初,使用 pandas 是因为我从 pandas 开始,并且 colnames 更好处理。但是,现在我需要集成到 sklearn-pipeline 中。
如何转换我的 Transformer 以支持来自 sklearn 管道 的 numpy 数组,而不是 pandas 数据帧?
关键是 self.colname
不能用于 numpy 数组,我认为分组需要以不同的方式执行。
如何实现此类转换器的持久性,因为这些权重需要可从磁盘加载,以便在管道中部署此类转换器。
class PercentageTransformer(TransformerMixin):
def __init__(self, colname,typePercentage='totalTarget', _target='TARGET', _dropOriginal=True):
self.colname = colname
self._target = _target
self._dropOriginal = _dropOriginal
self.typePercentage = typePercentage
def fit(self, X, y, *_):
original = pd.concat([y,X], axis=1)
grouped = original.groupby([self.colname, self._target]).size()
if self.typePercentage == 'totalTarget':
df = grouped / original[self._target].sum()
else:
df = (grouped / grouped.groupby(level=0).sum())
if self.typePercentage == 'totalTarget':
nameCol = "pre_" + self.colname
else:
nameCol = "pre2_" + self.colname
self.nameCol = nameCol
grouped = df.reset_index(name=nameCol)
groupedOnly = grouped[grouped[self._target] == 1]
groupedOnly = groupedOnly.drop(self._target, 1)
self.result = groupedOnly
return self
def transform(self, dataF):
mergedThing = pd.merge(dataF, self.result, on=self.colname, how='left')
mergedThing.loc[(mergedThing[self.nameCol].isnull()), self.nameCol] = 0
if self._dropOriginal:
mergedThing = mergedThing.drop(self.colname, 1)
return mergedThing
它会在这样的管道中使用:
pipeline = Pipeline([
('features', FeatureUnion([
('continuous', Pipeline([
('extract', ColumnExtractor(CONTINUOUS_FIELDS)),
])),
('factors', Pipeline([
('extract', ColumnExtractor(FACTOR_FIELDS)),
# using labelencoding and all bias
('bias', PercentageAllTransformer(FACTOR_FIELDS, _dropOriginal=True, typePercentage='totalTarget')),
]))
], n_jobs=-1)),
('estimator', estimator)
])
pipeline
将配备 X
和 y
,两者都是数据帧。我不确定X.as_matrix
是否会有所帮助。
【问题讨论】:
pandas
对象是 numpy
对象的包装器。没有pandas
数组,相信你的意思是Series
?无论如何,也许您的问题只需返回 self.values
而不是 self
就可以解决。
关于持久性,有几种方法可以解决。 Python中的对象序列化一般会使用pickle
模块。
确实我的意思是熊猫数据框。关键是如果我理解正确:原始original.groupby([self.colname, self._target]
不再是数据框,而是一个numpy数组,例如colnames 不再起作用。所以 self.values 似乎还不够。
否,groupby
返回一个groupby
对象,通常用于生成新的DataFrame
。您不能像往常一样访问self.colname, self._target
,因为默认情况下,这些用作index
到新的DataFrame
。将as_index=False
传递给groupby
以将您的分组列保留为列。
【参考方案1】:
来回转换事物
Pandas 有一个 .to_records() 方法,正如你提到的,还有一个 .as_matrix() 方法。 .to_records() 方法实际上会为您保留列名。 Numpy 确实支持数组中的命名列。见here。
坚持Pandas 有一个 pandas.to_pickle(obj, filename) 方法,它接受一个 pandas 对象和pickles 它。有对应的 pandas.read_pickle(filename) 方法。
Numpy 也有 save 和 load 函数。
【讨论】:
以上是关于用于 sklearn 管道的 pandas 到 numpy 数组的主要内容,如果未能解决你的问题,请参考以下文章
管道中的 Sklearn_pandas 返回 TypeError: 'builtin_function_or_method' object is not iterable
Groupby 在一列 pandas 数据帧上,并使用 GridsearchCv 使用通用 sklearn 管道训练每个组的特征和目标 (X, y)