@@ -242,14 +242,30 @@ def __new__(cls, levels=None, codes=None, sortorder=None, names=None,
242
242
result .sortorder = sortorder
243
243
244
244
if verify_integrity :
245
- result ._verify_integrity ()
245
+ new_codes = result ._verify_integrity ()
246
+ result ._codes = new_codes
246
247
247
248
if _set_identity :
248
249
result ._reset_identity ()
249
250
250
251
return result
251
252
252
- def _validate_codes (cls , level , code ):
253
+ def _validate_codes (self , level , code ):
254
+ """
255
+ Reassign code values as -1 if their corresponding levels are NaN.
256
+
257
+ Parameters
258
+ ----------
259
+ code : optional list
260
+ Code to reassign.
261
+ level : optional list
262
+ Level to check for Nan.
263
+
264
+ Returns
265
+ -------
266
+ code : new code where code value = -1 if it corresponds
267
+ to a NaN level.
268
+ """
253
269
null_mask = isna (level )
254
270
if np .any (null_mask ):
255
271
code = np .where (null_mask [code ], - 1 , code )
@@ -270,6 +286,11 @@ def _verify_integrity(self, codes=None, levels=None):
270
286
ValueError
271
287
If length of levels and codes don't match, if the codes for any
272
288
level would exceed level bounds, or there are any duplicate levels.
289
+
290
+ Returns
291
+ -------
292
+ codes : new codes where code value = -1 if it corresponds to a
293
+ NaN level.
273
294
"""
274
295
# NOTE: Currently does not check, among other things, that cached
275
296
# nlevels matches nor that sortorder matches actually sortorder.
@@ -279,18 +300,18 @@ def _verify_integrity(self, codes=None, levels=None):
279
300
if len (levels ) != len (codes ):
280
301
raise ValueError ("Length of levels and codes must match. NOTE:"
281
302
" this index is in an inconsistent state." )
282
- codes_length = len (self . codes [0 ])
303
+ codes_length = len (codes [0 ])
283
304
for i , (level , level_codes ) in enumerate (zip (levels , codes )):
284
305
if len (level_codes ) != codes_length :
285
306
raise ValueError ("Unequal code lengths: %s" %
286
307
([len (code_ ) for code_ in codes ]))
287
308
if len (level_codes ) and level_codes .max () >= len (level ):
288
- raise ValueError ("On level {level}, code max ({max_code})"
289
- " >= length of level ({level_len}). "
290
- "NOTE: this index is in an inconsistent"
291
- " state" . format (
292
- level = i , max_code = level_codes . max (),
293
- level_len = len ( level )) )
309
+ msg = ("On level {level}, code max ({max_code}) >= length of "
310
+ " level ({level_len}). NOTE: this index is in an "
311
+ " inconsistent state" . format (
312
+ level = i , max_code = level_codes . max (),
313
+ level_len = len ( level )))
314
+ raise ValueError ( msg )
294
315
if len (level_codes ) and level_codes .min () < - 1 :
295
316
raise ValueError ("On level {level}, code value ({code})"
296
317
" < -1" .format (
@@ -301,9 +322,9 @@ def _verify_integrity(self, codes=None, levels=None):
301
322
values = [value for value in level ],
302
323
level = i ))
303
324
304
- codes = [self ._validate_codes (level , code )
305
- for level , code in zip (levels , codes )]
306
- self . _set_codes ( codes , validate = False )
325
+ codes = FrozenList ( [self ._validate_codes (level , code )
326
+ for level , code in zip (levels , codes )])
327
+ return codes
307
328
308
329
@classmethod
309
330
def from_arrays (cls , arrays , sortorder = None , names = None ):
@@ -603,7 +624,8 @@ def _set_levels(self, levels, level=None, copy=False, validate=True,
603
624
new_levels = FrozenList (new_levels )
604
625
605
626
if verify_integrity :
606
- self ._verify_integrity (levels = new_levels )
627
+ new_codes = self ._verify_integrity (levels = new_levels )
628
+ self ._codes = new_codes
607
629
608
630
names = self .names
609
631
self ._levels = new_levels
@@ -711,10 +733,8 @@ def _set_codes(self, codes, level=None, copy=False, validate=True,
711
733
level_codes , lev , copy = copy )._shallow_copy ()
712
734
new_codes = FrozenList (new_codes )
713
735
714
- if verify_integrity :
715
- self ._verify_integrity (codes = new_codes )
716
- else :
717
- self ._codes = new_codes
736
+ new_codes = self ._verify_integrity (codes = new_codes )
737
+ self ._codes = new_codes
718
738
719
739
self ._tuples = None
720
740
self ._reset_cache ()
@@ -1778,9 +1798,10 @@ def __setstate__(self, state):
1778
1798
1779
1799
self ._set_levels ([Index (x ) for x in levels ], validate = False )
1780
1800
self ._set_codes (codes )
1801
+ new_codes = self ._verify_integrity ()
1802
+ self ._set_codes (new_codes )
1781
1803
self ._set_names (names )
1782
1804
self .sortorder = sortorder
1783
- self ._verify_integrity ()
1784
1805
self ._reset_identity ()
1785
1806
1786
1807
def __getitem__ (self , key ):
0 commit comments