Parsing and scaling numeric features#
Converting heterogeneous numeric values to uniform float32#
Many tabular datasets stored as csv files contain numeric information stored as strings, mixed representations, locale-specific formats, or other non-standard encodings. Common issues include:
Thousands separators (
1,234.56or1 234,56)Use of apostrophes as separators (
4'567.89)Negative numbers encoded inside parentheses (
(1,234.56))String columns that contain mostly numeric values, but with occasional invalid entries
To provide consistent numeric behavior, skrub includes the ToFloat transformer,
which standardizes all numeric-like columns to float32 and handles a wide
range of real-world formatting issues automatically. Columns that cannot be parsed
are rejected with a RejectColumn exception.
Converting numbers to float32 has the advantage of reducing memory pressure,
while retaining most of the information for training models.
>>> import pandas as pd
>>> from skrub import ToFloat
>>> s = pd.Series(['1.1', None, '3.3'], name='x')
>>> to_float = ToFloat()
>>> to_float.fit_transform(s)
0 1.1
1 NaN
2 3.3
Name: x, dtype: float32
If the transformer is fitted correctly, invalid values encountered at transform
time are replaced by NaN:
>>> to_float.transform(pd.Series(['3.3', 'invalid'], name='x'))
0 3.3
1 NaN
Name: x, dtype: float32
Locale-dependent decimal separators can be handled by specifying the
decimal and thousand parameter. Here we use comma as decimal separator, and
a space as thousands separators:
>>> s = pd.Series(["4 567,89", "12 567,89"], name="x")
>>> ToFloat(decimal=",", thousand=" ").fit_transform(s)
0 4567.8...
1 12567.8...
Name: x, dtype: float32
In some contexts, negative numbers may be represented with parentheses, instead of
using -. This case is handled by the parentheses boolean parameter:
>>> s = pd.Series(["-1,234.56", "(1,234.56)"], name="neg")
>>> ToFloat(thousand=",", parentheses=True).fit_transform(s)
0 -1234.5...
1 -1234.5...
Name: neg, dtype: float32
Robust scaling of numeric features using SquashingScaler#
The SquashingScaler is a robust scaler for numeric features, particularly
useful when features include outliers (such as infinite values); missing values
are left unchanged (they are not interpolated).
The SquashingScaler centers and scales the data in such a way that outliers are
less likely to skew the final result compared to alternative methods.
Based on the specified quantile_range parameter, the scaler employs a scikit-learn
RobustScaler to rescale the values in a way that the quantile range occupies
interval of length two, centering the median to zero. It therefore ensures that
inliers are spread to a reasonable range. Afterwards, it uses a smooth clipping
function to ensure all values (including outliers and infinite values) are in the
range [-max_absolute_value, max_absolute_value]. By default,
max_absolute_value=3.
>>> import pandas as pd
>>> import numpy as np
>>> from skrub import SquashingScaler
>>> X = pd.DataFrame(dict(col=[np.inf, -np.inf, 3, -1, np.nan, 2]))
>>> SquashingScaler(max_absolute_value=3).fit_transform(X)
array([[ 3. ],
[-3. ],
[ 0.49319696],
[-1.34164079],
[ nan],
[ 0. ]])
More information about the theory behind the scaler is available in the
SquashingScaler documentation, while this
working example compares
different scalers when used on data that include outliers.