1
+ import narwhals as nw
1
2
import numpy as np
2
3
import pytest
3
4
10
11
from tests .imputers .test_BaseImputer import (
11
12
GenericImputerTransformTests ,
12
13
)
14
+ from tests .utils import assert_frame_equal_dispatch , dataframe_init_dispatch
13
15
from tubular .imputers import NearestMeanResponseImputer
14
16
15
17
@@ -42,18 +44,23 @@ def test_null_values_in_response_error(self, library):
42
44
transformer .fit (df , df ["a" ])
43
45
44
46
@pytest .mark .parametrize ("library" , ["pandas" , "polars" ])
45
- def test_columns_with_no_nulls_error (self , library ):
46
- """Test an error is raised if a non-response column contains no nulls."""
47
+ def test_columns_with_no_nulls_warning (self , library ):
48
+ """Test a warning is raised if a non-response column contains no nulls."""
47
49
df = d .create_numeric_df_1 (library = library )
48
50
49
- transformer = NearestMeanResponseImputer (columns = ["b" , " c" ])
51
+ transformer = NearestMeanResponseImputer (columns = ["c" ])
50
52
51
- with pytest .raises (
52
- ValueError ,
53
- match = "NearestMeanResponseImputer: Column b has no missing values, cannot use this transformer ." ,
53
+ with pytest .warns (
54
+ UserWarning ,
55
+ match = "NearestMeanResponseImputer: Column c has no missing values, this transformer will have no effect for this column ." ,
54
56
):
55
57
transformer .fit (df , df ["c" ])
56
58
59
+ expected_impute_values = {"c" : None }
60
+ assert (
61
+ transformer .impute_values_ == expected_impute_values
62
+ ), f"impute_values_ attr not as expected, expected { expected_impute_values } but got { transformer .impute_values_ } "
63
+
57
64
@pytest .mark .parametrize ("library" , ["pandas" , "polars" ])
58
65
def test_learnt_values (self , library ):
59
66
"""Test that the nearest response values learnt during fit are expected."""
@@ -78,3 +85,48 @@ class TestTransform(
78
85
@classmethod
79
86
def setup_class (cls ):
80
87
cls .transformer_name = "NearestMeanResponseImputer"
88
+
89
+ @pytest .mark .parametrize ("library" , ["pandas" , "polars" ])
90
+ @pytest .mark .parametrize (
91
+ ("fit_col" , "transform_col" ),
92
+ [
93
+ # try a few types, with and without nulls in transform col
94
+ ([1 , 2 , 3 ], [1.0 , np .nan , np .nan ]),
95
+ ([4 , 5 , 6 ], [7 , 8 , 9 ]),
96
+ (["a" , "b" , "c" ], ["a" , None , "d" ]),
97
+ (["c" , "d" , "e" ], ["f" , "g" , "h" ]),
98
+ ([4.0 , 5.0 , 6.0 ], [8.0 , np .nan , 6.0 ]),
99
+ ([1.0 , 2.0 , 3.0 ], [4.0 , 3.0 , 2.0 ]),
100
+ ([True , False , False ], [True , True , None ]),
101
+ ([True , False , True ], [True , False , True ]),
102
+ ],
103
+ )
104
+ def test_no_effect_when_fit_on_null_free_col (self , fit_col , transform_col , library ):
105
+ "test that when transformer fits on a col with no nulls, transform has no effect"
106
+
107
+ df_fit_dict = {
108
+ "a" : fit_col ,
109
+ "b" : [1 ] * len (fit_col ),
110
+ }
111
+
112
+ df_fit = dataframe_init_dispatch (df_fit_dict , library = library )
113
+
114
+ df_transform_dict = {
115
+ "a" : transform_col ,
116
+ }
117
+
118
+ df_transform = dataframe_init_dispatch (df_transform_dict , library = library )
119
+
120
+ transformer = NearestMeanResponseImputer (columns = ["a" ])
121
+
122
+ transformer .fit (df_fit , df_fit ["b" ])
123
+
124
+ df_transform = nw .from_native (df_transform )
125
+
126
+ expected_output = df_transform .clone ().to_native ()
127
+
128
+ df_transform = nw .to_native (df_transform )
129
+
130
+ output = transformer .transform (df_transform )
131
+
132
+ assert_frame_equal_dispatch (output , expected_output )
0 commit comments