Skip to content

Commit 972359f

Browse files
committed
port solution from pandas-dev#35417
1 parent e52db7d commit 972359f

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

pandas/_libs/reduction.pyx

+29-8
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,8 @@ cdef class BlockSlider:
400400
object frame, dummy, index
401401
int nblocks
402402
Slider idx_slider
403-
list blocks
403+
list blocks, blk_values
404+
ndarray orig_blklocs, orig_blknos
404405

405406
cdef:
406407
char **base_ptrs
@@ -414,20 +415,27 @@ cdef class BlockSlider:
414415
self.dummy = frame[:0]
415416
self.index = self.dummy.index
416417

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]
418424

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:
420428
util.set_array_not_contiguous(x)
421429

422-
self.nblocks = len(self.blocks)
430+
self.nblocks = len(self.blk_values)
423431
# See the comment in indexes/base.py about _index_data.
424432
# We need this for EA-backed indexes that have a reference to a 1-d
425433
# ndarray like datetime / timedelta / period.
426434
self.idx_slider = Slider(
427435
self.frame.index._index_data, self.dummy.index._index_data)
428436

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):
431439
self.base_ptrs[i] = (<ndarray>block).data
432440

433441
def __dealloc__(self):
@@ -438,9 +446,11 @@ cdef class BlockSlider:
438446
ndarray arr
439447
Py_ssize_t i
440448

449+
self._restore_blocks()
450+
441451
# move blocks
442452
for i in range(self.nblocks):
443-
arr = self.blocks[i]
453+
arr = self.blk_values[i]
444454

445455
# axis=1 is the frame's axis=0
446456
arr.data = self.base_ptrs[i] + arr.strides[1] * start
@@ -453,14 +463,25 @@ cdef class BlockSlider:
453463
self.index._engine.clear_mapping()
454464
self.index._cache.clear() # e.g. inferred_freq must go
455465

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+
456475
cdef reset(self):
457476
cdef:
458477
ndarray arr
459478
Py_ssize_t i
460479

480+
self._restore_blocks()
481+
461482
# reset blocks
462483
for i in range(self.nblocks):
463-
arr = self.blocks[i]
484+
arr = self.blk_values[i]
464485

465486
# axis=1 is the frame's axis=0
466487
arr.data = self.base_ptrs[i]

0 commit comments

Comments
 (0)