@@ -400,7 +400,8 @@ cdef class BlockSlider:
400
400
object frame, dummy, index
401
401
int nblocks
402
402
Slider idx_slider
403
- list blocks
403
+ list blocks, blk_values
404
+ ndarray orig_blklocs, orig_blknos
404
405
405
406
cdef:
406
407
char ** base_ptrs
@@ -414,20 +415,27 @@ cdef class BlockSlider:
414
415
self .dummy = frame[:0 ]
415
416
self .index = self .dummy.index
416
417
417
- self .blocks = [b.values for b in self .dummy._mgr.blocks]
418
+ # GH#35417 attributes we need to restore at each step in case
419
+ # the function modified them.
420
+ mgr = self .dummy._mgr
421
+ self .orig_blklocs = mgr.blklocs
422
+ self .orig_blknos = mgr.blknos
423
+ self .blocks = [x for x in self .dummy._mgr.blocks]
418
424
419
- for x in self .blocks:
425
+ self .blk_values = [b.values for b in self .dummy._mgr.blocks]
426
+
427
+ for x in self .blk_values:
420
428
util.set_array_not_contiguous(x)
421
429
422
- self .nblocks = len (self .blocks )
430
+ self .nblocks = len (self .blk_values )
423
431
# See the comment in indexes/base.py about _index_data.
424
432
# We need this for EA-backed indexes that have a reference to a 1-d
425
433
# ndarray like datetime / timedelta / period.
426
434
self .idx_slider = Slider(
427
435
self .frame.index._index_data, self .dummy.index._index_data)
428
436
429
- self .base_ptrs = < char ** > malloc(sizeof(char * ) * len (self .blocks ))
430
- for i, block in enumerate (self .blocks ):
437
+ self .base_ptrs = < char ** > malloc(sizeof(char * ) * len (self .blk_values ))
438
+ for i, block in enumerate (self .blk_values ):
431
439
self .base_ptrs[i] = (< ndarray> block).data
432
440
433
441
def __dealloc__ (self ):
@@ -438,9 +446,11 @@ cdef class BlockSlider:
438
446
ndarray arr
439
447
Py_ssize_t i
440
448
449
+ self ._restore_blocks()
450
+
441
451
# move blocks
442
452
for i in range (self .nblocks):
443
- arr = self .blocks [i]
453
+ arr = self .blk_values [i]
444
454
445
455
# axis=1 is the frame's axis=0
446
456
arr.data = self .base_ptrs[i] + arr.strides[1 ] * start
@@ -453,14 +463,25 @@ cdef class BlockSlider:
453
463
self .index._engine.clear_mapping()
454
464
self .index._cache.clear() # e.g. inferred_freq must go
455
465
466
+ cdef _restore_blocks(self ):
467
+ """
468
+ Ensure that we have the original blocks, blknos, and blklocs.
469
+ """
470
+ mgr = self .dummy._mgr
471
+ mgr.blocks = self .blocks
472
+ mgr._blklocs = self .orig_blklocs
473
+ mgr._blknos = self .orig_blknos
474
+
456
475
cdef reset(self ):
457
476
cdef:
458
477
ndarray arr
459
478
Py_ssize_t i
460
479
480
+ self ._restore_blocks()
481
+
461
482
# reset blocks
462
483
for i in range (self .nblocks):
463
- arr = self .blocks [i]
484
+ arr = self .blk_values [i]
464
485
465
486
# axis=1 is the frame's axis=0
466
487
arr.data = self .base_ptrs[i]
0 commit comments