-
-
Notifications
You must be signed in to change notification settings - Fork 260
Expand file tree
/
Copy path_column_transformer.py
More file actions
224 lines (191 loc) · 9.08 KB
/
Copy path_column_transformer.py
File metadata and controls
224 lines (191 loc) · 9.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
import warnings
import dask.array as da
import dask.dataframe as dd
import numpy as np
import pandas as pd
import sklearn.compose
from scipy import sparse
from sklearn.compose._column_transformer import _get_transformer_list
class ColumnTransformer(sklearn.compose.ColumnTransformer):
"""Applies transformers to columns of an array or pandas DataFrame.
EXPERIMENTAL: some behaviors may change between releases without
deprecation.
This estimator allows different columns or column subsets of the input
to be transformed separately and the results combined into a single
feature space.
This is useful for heterogeneous or columnar data, to combine several
feature extraction mechanisms or transformations into a single transformer.
Read more in the :ref:`User Guide <column_transformer>`.
.. versionadded:: 0.9.0
.. note::
This requires scikit-learn 0.20.0 or newer.
Parameters
----------
transformers : list of tuples
List of (name, transformer, column(s)) tuples specifying the
transformer objects to be applied to subsets of the data.
name : string
Like in Pipeline and FeatureUnion, this allows the transformer and
its parameters to be set using ``set_params`` and searched in grid
search.
transformer : estimator or {'passthrough', 'drop'}
Estimator must support `fit` and `transform`. Special-cased
strings 'drop' and 'passthrough' are accepted as well, to
indicate to drop the columns or to pass them through untransformed,
respectively.
column(s) : string or int, array-like of string or int, slice, \
boolean mask array or callable
Indexes the data on its second axis. Integers are interpreted as
positional columns, while strings can reference DataFrame columns
by name. A scalar string or int should be used where
``transformer`` expects X to be a 1d array-like (vector),
otherwise a 2d array will be passed to the transformer.
A callable is passed the input data `X` and can return any of the
above.
remainder : {'drop', 'passthrough'} or estimator, default 'drop'
By default, only the specified columns in `transformers` are
transformed and combined in the output, and the non-specified
columns are dropped. (default of ``'drop'``).
By specifying ``remainder='passthrough'``, all remaining columns that
were not specified in `transformers` will be automatically passed
through. This subset of columns is concatenated with the output of
the transformers.
By setting ``remainder`` to be an estimator, the remaining
non-specified columns will use the ``remainder`` estimator. The
estimator must support `fit` and `transform`.
sparse_threshold : float, default = 0.3
If the transformed output consists of a mix of sparse and dense data,
it will be stacked as a sparse matrix if the density is lower than this
value. Use ``sparse_threshold=0`` to always return dense.
When the transformed output consists of all sparse or all dense data,
the stacked result will be sparse or dense, respectively, and this
keyword will be ignored.
n_jobs : int or None, optional (default=None)
Number of jobs to run in parallel.
``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
``-1`` means using all processors. See :term:`Glossary <n_jobs>`
for more details.
transformer_weights : dict, optional
Multiplicative weights for features per transformer. The output of the
transformer is multiplied by these weights. Keys are transformer names,
values the weights.
preserve_dataframe : bool, (default=True)
Whether to preserve preserve pandas DataFrames when concatenating
the results.
.. warning::
The default behavior of keeping DataFrames differs from
scikit-learn's current behavior. Set ``preserve_dataframe=False``
if you need to ensure that the output matches scikit-learn's
ColumnTransformer.
Attributes
----------
transformers_ : list
The collection of fitted transformers as tuples of
(name, fitted_transformer, column). `fitted_transformer` can be an
estimator, 'drop', or 'passthrough'. If there are remaining columns,
the final element is a tuple of the form:
('remainder', transformer, remaining_columns) corresponding to the
``remainder`` parameter. If there are remaining columns, then
``len(transformers_)==len(transformers)+1``, otherwise
``len(transformers_)==len(transformers)``.
named_transformers_ : Bunch object, a dictionary with attribute access
Read-only attribute to access any transformer by given name.
Keys are transformer names and values are the fitted transformer
objects.
sparse_output_ : boolean
Boolean flag indicating whether the output of ``transform`` is a
sparse matrix or a dense numpy array, which depends on the output
of the individual transformers and the `sparse_threshold` keyword.
Notes
-----
The order of the columns in the transformed feature matrix follows the
order of how the columns are specified in the `transformers` list.
Columns of the original feature matrix that are not specified are
dropped from the resulting transformed feature matrix, unless specified
in the `passthrough` keyword. Those columns specified with `passthrough`
are added at the right to the output of the transformers.
See also
--------
dask_ml.compose.make_column_transformer : convenience function for
combining the outputs of multiple transformer objects applied to
column subsets of the original feature space.
Examples
--------
>>> from dask.ml.compose import ColumnTransformer
>>> from sklearn.preprocessing import Normalizer
>>> ct = ColumnTransformer(
... [("norm1", Normalizer(norm='l1'), [0, 1]),
... ("norm2", Normalizer(norm='l1'), slice(2, 4))])
>>> X = np.array([[0., 1., 2., 2.],
... [1., 1., 0., 1.]])
>>> # Normalizer scales each row of X to unit norm. A separate scaling
>>> # is applied for the two first and two last elements of each
>>> # row independently.
>>> ct.fit_transform(X) # doctest: +NORMALIZE_WHITESPACE
array([[0. , 1. , 0.5, 0.5],
[0.5, 0.5, 0. , 1. ]])
"""
def __init__(
self,
transformers,
remainder="drop",
sparse_threshold=0.3,
n_jobs=1,
transformer_weights=None,
preserve_dataframe=True,
):
self.preserve_dataframe = preserve_dataframe
super(ColumnTransformer, self).__init__(
transformers=transformers,
remainder=remainder,
sparse_threshold=sparse_threshold,
n_jobs=n_jobs,
transformer_weights=transformer_weights,
)
def _hstack(self, Xs):
"""
Stacks X horizontally.
Supports input types (X): list of
numpy arrays, sparse arrays and DataFrames
"""
types = set(type(X) for X in Xs)
if self.sparse_output_:
return sparse.hstack(Xs).tocsr()
elif dd.Series in types or dd.DataFrame in types:
with warnings.catch_warnings():
warnings.filterwarnings("ignore", "Concatenating", UserWarning)
return dd.concat(Xs, axis="columns")
elif da.Array in types:
# To allow compatibility with dask core 1.0.0, this is the `else`
# part of the definition of the dask.array.hstack inlined.
# The `then` branch is removed because _validate_output in
# sklearn.compose.ColumnTransformer ensures ndim == 2, so the
# check `all(x.ndim == 1 for x in Xs)` should always fail.
#
# Once dask.array.hstack supports allow_unknown_chunksizes,
# changed this to da.hstack(Xs, allow_unknown_chunksizes=True)
return da.concatenate(Xs, axis=1, allow_unknown_chunksizes=True)
elif self.preserve_dataframe and (pd.Series in types or pd.DataFrame in types):
return pd.concat(Xs, axis="columns")
else:
return np.hstack(Xs)
def make_column_transformer(*transformers, **kwargs):
# This is identical to scikit-learn's. We're just using our
# ColumnTransformer instead.
n_jobs = kwargs.pop("n_jobs", 1)
remainder = kwargs.pop("remainder", "drop")
preserve_dataframe = kwargs.pop("preserve_dataframe", True)
if kwargs:
raise TypeError(
'Unknown keyword arguments: "{}"'.format(list(kwargs.keys())[0])
)
transformer_list = _get_transformer_list(transformers)
return ColumnTransformer(
transformer_list,
n_jobs=n_jobs,
remainder=remainder,
preserve_dataframe=preserve_dataframe,
)
make_column_transformer.__doc__ = getattr(
sklearn.compose.make_column_transformer, "__doc__"
)