@@ -108,6 +108,146 @@ def test_from_numpy_sparse(self):
108
108
t = Table .from_numpy (domain , sp .bsr_matrix (x ))
109
109
self .assertTrue (sp .isspmatrix_csr (t .X ))
110
110
111
+ @staticmethod
112
+ def _new_table (attrs , classes , metas , s ):
113
+ def nz (x ): # pylint: disable=invalid-name
114
+ return x if x .size else np .empty ((5 , 0 ))
115
+
116
+ domain = Domain (attrs , classes , metas )
117
+ X = np .arange (s , s + len (attrs ) * 5 ).reshape (5 , - 1 )
118
+ Y = np .arange (100 + s , 100 + s + len (classes ) * 5 )
119
+ if len (classes ) > 1 :
120
+ Y = Y .reshape (5 , - 1 )
121
+ M = np .arange (200 + s , 200 + s + len (metas ) * 5 ).reshape (5 , - 1 )
122
+ return Table .from_numpy (domain , nz (X ), nz (Y ), nz (M ))
123
+
124
+ def test_concatenate_horizontal (self ):
125
+ a , b , c , d , e , f , g = map (ContinuousVariable , "abcdefg" )
126
+
127
+ # Common case; one class, no empty's
128
+ tab1 = self ._new_table ((a , b ), (c , ), (d , ), 0 )
129
+ tab2 = self ._new_table ((e , ), (), (f , g ), 1000 )
130
+ joined = Table .concatenate ((tab1 , tab2 ), axis = 1 )
131
+ domain = joined .domain
132
+ self .assertEqual (domain .attributes , (a , b , e ))
133
+ self .assertEqual (domain .class_vars , (c , ))
134
+ self .assertEqual (domain .metas , (d , f , g ))
135
+ np .testing .assert_equal (joined .X , np .hstack ((tab1 .X , tab2 .X )))
136
+ np .testing .assert_equal (joined .Y , tab1 .Y )
137
+ np .testing .assert_equal (joined .metas , np .hstack ((tab1 .metas , tab2 .metas )))
138
+
139
+ # One part of one table is empty
140
+ tab1 = self ._new_table ((a , b ), (), (), 0 )
141
+ tab2 = self ._new_table ((), (), (c , ), 1000 )
142
+ joined = Table .concatenate ((tab1 , tab2 ), axis = 1 )
143
+ domain = joined .domain
144
+ self .assertEqual (domain .attributes , (a , b ))
145
+ self .assertEqual (domain .class_vars , ())
146
+ self .assertEqual (domain .metas , (c , ))
147
+ np .testing .assert_equal (joined .X , np .hstack ((tab1 .X , tab2 .X )))
148
+ np .testing .assert_equal (joined .metas , np .hstack ((tab1 .metas , tab2 .metas )))
149
+
150
+ # Multiple classes, two empty parts are merged
151
+ tab1 = self ._new_table ((a , b ), (c , ), (), 0 )
152
+ tab2 = self ._new_table ((), (d , ), (), 1000 )
153
+ joined = Table .concatenate ((tab1 , tab2 ), axis = 1 )
154
+ domain = joined .domain
155
+ self .assertEqual (domain .attributes , (a , b ))
156
+ self .assertEqual (domain .class_vars , (c , d ))
157
+ self .assertEqual (domain .metas , ())
158
+ np .testing .assert_equal (joined .X , np .hstack ((tab1 .X , tab2 .X )))
159
+ np .testing .assert_equal (joined .Y , np .vstack ((tab1 .Y , tab2 .Y )).T )
160
+
161
+ # Merging of attributes and selection of weights
162
+ tab1 = self ._new_table ((a , b ), (c , ), (), 0 )
163
+ tab1 .attributes = dict (a = 5 , b = 7 )
164
+ tab2 = self ._new_table ((d , ), (e , ), (), 1000 )
165
+ tab2 .W = np .arange (5 )
166
+ tab3 = self ._new_table ((f , g ), (), (), 2000 )
167
+ tab3 .attributes = dict (a = 1 , c = 4 )
168
+ tab3 .W = np .arange (5 , 10 )
169
+ joined = Table .concatenate ((tab1 , tab2 , tab3 ), axis = 1 )
170
+ domain = joined .domain
171
+ self .assertEqual (domain .attributes , (a , b , d , f , g ))
172
+ self .assertEqual (domain .class_vars , (c , e ))
173
+ self .assertEqual (domain .metas , ())
174
+ np .testing .assert_equal (joined .X , np .hstack ((tab1 .X , tab2 .X , tab3 .X )))
175
+ np .testing .assert_equal (joined .Y , np .vstack ((tab1 .Y , tab2 .Y )).T )
176
+ self .assertEqual (joined .attributes , dict (a = 5 , b = 7 , c = 4 ))
177
+ np .testing .assert_equal (joined .ids , tab1 .ids )
178
+ np .testing .assert_equal (joined .W , tab2 .W )
179
+
180
+ # Raise an exception when no tables are given
181
+ self .assertRaises (ValueError , Table .concatenate , (), axis = 1 )
182
+
183
+ def test_concatenate_invalid_axis (self ):
184
+ self .assertRaises (ValueError , Table .concatenate , (), axis = 2 )
185
+
186
+ def test_concatenate_names (self ):
187
+ a , b , c , d , e , f , g = map (ContinuousVariable , "abcdefg" )
188
+
189
+ tab1 = self ._new_table ((a , ), (c , ), (d , ), 0 )
190
+ tab2 = self ._new_table ((e , ), (), (f , g ), 1000 )
191
+ tab3 = self ._new_table ((b , ), (), (), 1000 )
192
+ tab2 .name = "tab2"
193
+ tab3 .name = "tab3"
194
+
195
+ joined = Table .concatenate ((tab1 , tab2 , tab3 ), axis = 1 )
196
+ self .assertEqual (joined .name , "tab2" )
197
+
198
+ def test_with_column (self ):
199
+ a , b , c , d , e , f , g = map (ContinuousVariable , "abcdefg" )
200
+ col = np .arange (9 , 14 )
201
+ colr = col .reshape (5 , - 1 )
202
+ tab = self ._new_table ((a , b , c ), (d , ), (e , f ), 0 )
203
+
204
+ # Add to attributes
205
+ tabw = tab .add_column (g , np .arange (9 , 14 ))
206
+ self .assertEqual (tabw .domain .attributes , (a , b , c , g ))
207
+ np .testing .assert_equal (tabw .X , np .hstack ((tab .X , colr )))
208
+ np .testing .assert_equal (tabw .Y , tab .Y )
209
+ np .testing .assert_equal (tabw .metas , tab .metas )
210
+
211
+ # Add to metas
212
+ tabw = tab .add_column (g , np .arange (9 , 14 ), to_metas = True )
213
+ self .assertEqual (tabw .domain .metas , (e , f , g ))
214
+ np .testing .assert_equal (tabw .X , tab .X )
215
+ np .testing .assert_equal (tabw .Y , tab .Y )
216
+ np .testing .assert_equal (tabw .metas , np .hstack ((tab .metas , colr )))
217
+
218
+ # Add to empty attributes
219
+ tab = self ._new_table ((), (d , ), (e , f ), 0 )
220
+ tabw = tab .add_column (g , np .arange (9 , 14 ))
221
+ self .assertEqual (tabw .domain .attributes , (g , ))
222
+ np .testing .assert_equal (tabw .X , colr )
223
+ np .testing .assert_equal (tabw .Y , tab .Y )
224
+ np .testing .assert_equal (tabw .metas , tab .metas )
225
+
226
+ # Add to empty metas
227
+ tab = self ._new_table ((a , b , c ), (d , ), (), 0 )
228
+ tabw = tab .add_column (g , np .arange (9 , 14 ), to_metas = True )
229
+ self .assertEqual (tabw .domain .metas , (g , ))
230
+ np .testing .assert_equal (tabw .X , tab .X )
231
+ np .testing .assert_equal (tabw .Y , tab .Y )
232
+ np .testing .assert_equal (tabw .metas , colr )
233
+
234
+ # Pass values as a list
235
+ tab = self ._new_table ((a , ), (d , ), (e , f ), 0 )
236
+ tabw = tab .add_column (g , [4 , 2 , - 1 , 2 , 5 ])
237
+ self .assertEqual (tabw .domain .attributes , (a , g ))
238
+ np .testing .assert_equal (
239
+ tabw .X , np .array ([[0 , 1 , 2 , 3 , 4 ], [4 , 2 , - 1 , 2 , 5 ]]).T )
240
+
241
+ # Add non-primitives as metas; join `float` and `object` to `object`
242
+ tab = self ._new_table ((a , ), (d , ), (e , f ), 0 )
243
+ t = StringVariable ("t" )
244
+ tabw = tab .add_column (t , list ("abcde" ))
245
+ self .assertEqual (tabw .domain .attributes , (a , ))
246
+ self .assertEqual (tabw .domain .metas , (e , f , t ))
247
+ np .testing .assert_equal (
248
+ tabw .metas ,
249
+ np .hstack ((tab .metas , np .array (list ("abcde" )).reshape (5 , - 1 ))))
250
+
111
251
112
252
class TestTableFilters (unittest .TestCase ):
113
253
def setUp (self ):
0 commit comments