Skip to content

io.pytables: handle start/stop in remove and select_coords #4835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions pandas/io/pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ def remove(self, key, where=None, start=None, stop=None):
raise KeyError('No object named %s in the file' % key)

# remove the node
if where is None:
if where is None and start is None and stop is None:
s.group._f_remove(recursive=True)

# delete from the table
Expand Down Expand Up @@ -2139,11 +2139,9 @@ def write(self, **kwargs):
raise NotImplementedError(
"cannot write on an abstract storer: sublcasses should implement")

def delete(self, where=None, **kwargs):
"""support fully deleting the node in its entirety (only) - where
specification must be None
"""
if where is None:
def delete(self, where=None, start=None, stop=None, **kwargs):
""" support fully deleting the node in its entirety (only) - where specification must be None """
if where is None and start is None and stop is None:
self._handle.removeNode(self.group, recursive=True)
return None

Expand Down Expand Up @@ -3700,12 +3698,16 @@ def write_data_chunk(self, indexes, mask, values):
except Exception as detail:
raise TypeError("tables cannot write this data -> %s" % detail)

def delete(self, where=None, **kwargs):
def delete(self, where=None, start=None, stop=None, **kwargs):

# delete all rows (and return the nrows)
if where is None or not len(where):
nrows = self.nrows
self._handle.removeNode(self.group, recursive=True)
if start is None and stop is None:
nrows = self.nrows
self._handle.removeNode(self.group, recursive=True)
else:
nrows = self.table.removeRows(start=start, stop=stop)
self.table.flush()
return nrows

# infer the data kind
Expand All @@ -3714,7 +3716,7 @@ def delete(self, where=None, **kwargs):

# create the selection
table = self.table
self.selection = Selection(self, where, **kwargs)
self.selection = Selection(self, where, start=start, stop=stop, **kwargs)
values = self.selection.select_coords()

# delete the rows in reverse order
Expand Down Expand Up @@ -4297,7 +4299,7 @@ def select_coords(self):
generate the selection
"""
if self.condition is None:
return np.arange(self.table.nrows)
return np.arange(0, self.table.nrows)[self.start:self.stop]

return self.table.table.getWhereList(self.condition.format(),
start=self.start, stop=self.stop,
Expand Down
62 changes: 62 additions & 0 deletions pandas/io/tests/test_pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -2158,6 +2158,68 @@ def test_remove_where(self):
# self.assertRaises(ValueError, store.remove,
# 'wp2', [('column', ['A', 'D'])])

def test_remove_startstop(self):

with ensure_clean_store(self.path) as store:

wp = tm.makePanel()

# start
store.put('wp1', wp, format='t')
n = store.remove('wp1', start=32)
assert(n == 120-32)
result = store.select('wp1')
expected = wp.reindex(major_axis=wp.major_axis[:32//4])
assert_panel_equal(result, expected)

store.put('wp2', wp, format='t')
n = store.remove('wp2', start=-32)
assert(n == 32)
result = store.select('wp2')
expected = wp.reindex(major_axis=wp.major_axis[:-32//4])
assert_panel_equal(result, expected)

# stop
store.put('wp3', wp, format='t')
n = store.remove('wp3', stop=32)
assert(n == 32)
result = store.select('wp3')
expected = wp.reindex(major_axis=wp.major_axis[32//4:])
assert_panel_equal(result, expected)

store.put('wp4', wp, format='t')
n = store.remove('wp4', stop=-32)
assert(n == 120-32)
result = store.select('wp4')
expected = wp.reindex(major_axis=wp.major_axis[-32//4:])
assert_panel_equal(result, expected)

# start n stop
store.put('wp5', wp, format='t')
n = store.remove('wp5', start=16, stop=-16)
assert(n == 120-32)
result = store.select('wp5')
expected = wp.reindex(major_axis=wp.major_axis[:16//4]+wp.major_axis[-16//4:])
assert_panel_equal(result, expected)

store.put('wp6', wp, format='t')
n = store.remove('wp6', start=16, stop=16)
assert(n == 0)
result = store.select('wp6')
expected = wp.reindex(major_axis=wp.major_axis)
assert_panel_equal(result, expected)

# with where
date = wp.major_axis.take(np.arange(0,30,3))
crit = Term('major_axis=date')
store.put('wp7', wp, format='t')
n = store.remove('wp7', where=[crit], stop=80)
assert(n == 28)
result = store.select('wp7')
expected = wp.reindex(major_axis=wp.major_axis-wp.major_axis[np.arange(0,20,3)])
assert_panel_equal(result, expected)


def test_remove_crit(self):

with ensure_clean_store(self.path) as store:
Expand Down