Skip to content

Commit 8d9d42b

Browse files
committed
Merge remote-tracking branch 'upstream/main' into fix-tablereport-narrow-range
2 parents 659a032 + 7600cc0 commit 8d9d42b

15 files changed

Lines changed: 1710 additions & 1478 deletions

File tree

CHANGES.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ New Features
4444
columns (the bin count and edges, and numbers of low and high outliers). Now
4545
``json()`` contains all the information shown in the report html rendering,
4646
including the plots. :pr:`2164` by :user:`Jérôme Dockès <jeromedockes>`.
47+
- Added :func:`skrub.selectors.object` to select columns with the ``object``
48+
(pandas) or ``pl.Object`` (polars) dtype. :pr:`2171` by :user:`Omkar Kabde
49+
<omkar-334>`.
4750

4851
Changes
4952
-------
@@ -65,6 +68,12 @@ Changes
6568

6669
Bugfixes
6770
--------
71+
- :class:`MinHashEncoder` with the default ``hashing="fast"`` now uses every
72+
n-gram size in ``ngram_range`` (the upper bound is inclusive, as documented
73+
and as already done by ``hashing="murmur"``). Previously the largest size was
74+
dropped, so the default ``ngram_range=(2, 4)`` ignored 4-grams and a
75+
single-size range such as ``(3, 3)`` produced the same constant encoding for
76+
every string. :pr:`2168` by :user:`José Maia <glitch-ux>`.
6877
- A bug in how the :class:`TableVectorizer` and :class:`Cleaner` treated columns
6978
duration columns in pandas and polars has been fixed. Now, both classes convert
7079
durations to the total number of seconds (with fractional part). This is done
@@ -74,6 +83,9 @@ Bugfixes
7483
double dollar (``$$``) signs has been fixed.
7584
:pr:`2154` by :user:`Katerina Michenina <Michenina-Lab>`,
7685
:user:`CecilyTS <CecilyTS>`, :user:`Eve Rabin <eve2705>`.
86+
- An error that happened when running ``TableReport`` or ``column_associations``
87+
on some dataframes with non-string column names has been fixed in :pr:`2179`
88+
by :user:`Jérôme Dockès <jeromedockes>`.
7789

7890
Deprecations
7991
------------

doc/api_reference.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@
158158
"selectors.inv",
159159
"selectors.make_selector",
160160
"selectors.numeric",
161+
"selectors.object",
161162
"selectors.regex",
162163
"selectors.select",
163164
"selectors.string",

doc/modules/multi_column_operations/type_of_selectors.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Selectors based on column data types
7979
- :func:`~skrub.selectors.any_date`: Select columns with date or datetime data types
8080
- :func:`~skrub.selectors.categorical`: Select columns with categorical data types
8181
- :func:`~skrub.selectors.string`: Select columns with string data types
82+
- :func:`~skrub.selectors.object`: Select columns with the ``object`` (pandas) or ``pl.Object`` (polars) dtype
8283
- :func:`~skrub.selectors.boolean`: Select columns with boolean data types
8384

8485
Selectors based on column content and properties

pixi.lock

Lines changed: 1533 additions & 1416 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

skrub/_check_input.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,6 @@ def cast_column_names_to_strings(df):
2020

2121

2222
def _column_names_to_strings(column_names):
23-
non_string = [c for c in column_names if not isinstance(c, str)]
24-
if not non_string:
25-
return column_names
26-
warnings.warn(
27-
f"Some dataframe column names are not strings: {non_string}.\n"
28-
"All dataframe column names must be strings in skrub pipelines; "
29-
"converting to strings."
30-
)
3123
return list(map(str, column_names))
3224

3325

skrub/_column_associations.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,9 +302,11 @@ def _melt(df, left_col, right_col, val):
302302
def _melt_pandas(df, left_col, right_col, val):
303303
# Deal with multi-level index and columns
304304
if df.index.nlevels > 1:
305-
df.index = df.index.to_flat_index().astype("string")
305+
df.index = df.index.to_flat_index()
306+
df.index = df.index.astype("string")
306307
if df.columns.nlevels > 1:
307-
df.columns = df.columns.to_flat_index().astype("string")
308+
df.columns = df.columns.to_flat_index()
309+
df.columns = df.columns.astype("string")
308310
return df.melt(ignore_index=False, var_name=right_col, value_name=val).reset_index(
309311
names=left_col
310312
)

skrub/_data_ops/tests/test_data_ops.py

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -879,34 +879,42 @@ def test_concat_vertical_duplicate_cols():
879879
def test_concat_non_str_colname():
880880
int_columns = pd.DataFrame({0: [1, 2], 1: [3, 4]})
881881
string_columns = pd.DataFrame({"0": [1, 2], "1": [3, 4]})
882+
result = (
883+
skrub.as_data_op(int_columns)
884+
.skb.concat([skrub.as_data_op(string_columns)], axis=1)
885+
.skb.eval()
886+
)
887+
assert result.shape == (2, 4)
882888

883-
# check that a warning is raised because of non-string column name
884-
with pytest.warns(
885-
UserWarning, match="Some dataframe column names are not strings:"
886-
):
887-
skrub.as_data_op(int_columns).skb.concat(
888-
[skrub.as_data_op(string_columns)], axis=1
889-
)
890-
with pytest.warns(
891-
UserWarning, match="Some dataframe column names are not strings:"
892-
):
893-
skrub.as_data_op(int_columns).skb.concat(
894-
[skrub.as_data_op(int_columns)], axis=1
895-
)
889+
result = (
890+
skrub.as_data_op(int_columns)
891+
.skb.concat([skrub.as_data_op(int_columns)], axis=1)
892+
.skb.eval()
893+
)
894+
assert result.shape == (2, 4)
896895

897-
# no warnings raised when all column names are strings
898-
with warnings.catch_warnings():
899-
warnings.simplefilter("error")
900-
skrub.as_data_op(string_columns).skb.concat(
901-
[skrub.as_data_op(string_columns)], axis=1
902-
)
896+
result = (
897+
skrub.as_data_op(string_columns)
898+
.skb.concat([skrub.as_data_op(string_columns)], axis=1)
899+
.skb.eval()
900+
)
901+
assert result.shape == (2, 4)
903902

904-
# check that no warning is raised when concatenating vertically
905-
with warnings.catch_warnings():
906-
warnings.simplefilter("error")
907-
skrub.as_data_op(int_columns).skb.concat(
908-
[skrub.as_data_op(int_columns)], axis=0
909-
)
903+
result = (
904+
skrub.as_data_op(int_columns)
905+
.skb.concat([skrub.as_data_op(int_columns)], axis=0)
906+
.skb.eval()
907+
)
908+
assert result.shape == (4, 2)
909+
assert list(result.columns) == [0, 1]
910+
911+
result = (
912+
skrub.as_data_op(string_columns)
913+
.skb.concat([skrub.as_data_op(string_columns)], axis=0)
914+
.skb.eval()
915+
)
916+
assert result.shape == (4, 2)
917+
assert list(result.columns) == ["0", "1"]
910918

911919

912920
def test_concat_numpy_arrays():
@@ -928,6 +936,12 @@ def test_concat_numpy_arrays():
928936
np.testing.assert_array_equal(out, expected)
929937

930938

939+
def test_int_column_names():
940+
assert list(
941+
skrub.X(pd.DataFrame({0: [1, 2]})).skb.apply("passthrough").skb.eval().columns
942+
) == ["0"]
943+
944+
931945
def test_get_vars():
932946
a = skrub.var("a")
933947
b = skrub.var("b")

skrub/_data_ops/tests/test_errors.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import traceback
44

55
import numpy as np
6-
import pandas as pd
76
import pytest
87
from sklearn.datasets import make_classification
98
from sklearn.dummy import DummyClassifier
@@ -638,11 +637,6 @@ def test_unhashable():
638637
{skrub.choose_bool(name="b").if_else(0, 1)}
639638

640639

641-
def test_int_column_names():
642-
with pytest.warns(match="Some dataframe column names are not strings"):
643-
skrub.X(pd.DataFrame({0: [1, 2]})).skb.apply("passthrough")
644-
645-
646640
def test_mark_as_X_missing_cv():
647641
with pytest.raises(TypeError, match=".*you must also provide a splitter"):
648642
skrub.var("a").skb.mark_as_X(split_kwargs={"groups": None})

skrub/_fast_hash.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ def ngram_min_hash(
8282

8383
max_hash = MININT32
8484
min_hash = MAXINT32
85-
for atom_len in range(ngram_range[0], ngram_range[1]):
85+
# The upper bound is inclusive: all n-gram sizes such that
86+
# ``min_n <= n <= max_n`` are used, matching the documented behavior and
87+
# the ``murmur`` hashing path (see ``get_unique_ngrams``).
88+
for atom_len in range(ngram_range[0], ngram_range[1] + 1):
8689
atom = gen_atom(atom_len, seed=seed)
8790
# np.correlate is faster than np.convolve
8891
# the convolution gives a hash for each ngram

skrub/_minhash_encoder.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ class MinHashEncoder(TransformerMixin, SingleColumnTransformer):
107107
108108
>>> enc.transform(X)
109109
city_0 city_1 city_2 city_3 city_4
110-
0 -1.783375e+09 -1.588270e+09 -1.663592e+09 -1.819887e+09 -1.962594e+09
111-
1 -8.480470e+08 -1.766579e+09 -1.558912e+09 -1.485745e+09 -1.687299e+09
112-
2 -1.975829e+09 -2.095000e+09 -1.596521e+09 -1.817594e+09 -2.095693e+09
110+
0 -2.127555e+09 -2.111535e+09 -1.925126e+09 -1.819887e+09 -1.962594e+09
111+
1 -2.127555e+09 -2.111535e+09 -1.718267e+09 -1.485745e+09 -1.687299e+09
112+
2 -1.975829e+09 -2.095000e+09 -1.659302e+09 -1.817594e+09 -2.095693e+09
113113
3 -1.975829e+09 -2.095000e+09 -1.530721e+09 -1.459183e+09 -1.580988e+09
114114
"""
115115

0 commit comments

Comments
 (0)