Skip to content
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

adds reshaping functions to Images and Series #343

Merged
merged 2 commits into from
Aug 2, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
adds more generic reshape to Images and Series
  • Loading branch information
jwittenbach committed Aug 2, 2016
commit 72cb2bbf4dd0e9efe57cbfa5d304d8ee663d8165
22 changes: 16 additions & 6 deletions test/test_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,21 @@ def test_reshape_values(eng):
original = fromarray(arange(72).reshape(2, 6, 6), engine=eng)
arr = original.toarray()

reshaped = original.reshape_values(12, 3)
assert allclose(arr.reshape(2, 12, 3), reshaped.toarray())
assert allclose(arr.reshape(2, 12, 3), original.reshape(2, 12, 3).toarray())
assert allclose(arr.reshape(2, 4, 3, 3), original.reshape(2, 4, 3, 3).toarray())

reshaped = original.reshape_values(36)
assert allclose(arr.reshape(2, 36), reshaped.toarray())
# must converve number or elements
with pytest.raises(ValueError):
original.reshape(2, 3, 6)

# cannot change number of images
with pytest.raises(ValueError):
original.reshape(4, 3, 6)

reshaped = original.reshape_values(4, 3, 3)
assert allclose(arr.reshape(2, 4, 3, 3), reshaped.toarray())
# cannot create images with less than 2 dimensions
with pytest.raises(ValueError):
original.reshape(2, 36)

# cannot create images with more than 3 dimensions
with pytest.raises(ValueError):
original.reshape(2, 2, 2, 3, 3)
17 changes: 10 additions & 7 deletions test/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,15 +429,18 @@ def test_mean_by_window(eng):
test4 = data.mean_by_window(indices=[3], window=4).toarray()
assert allclose(test4, [1, 2, 3, 4])

def test_reshape_keys(eng):
def test_reshape(eng):
original = fromarray(arange(72).reshape(6, 6, 2), engine=eng)
arr = original.toarray()

reshaped = original.reshape_keys(12, 3)
assert allclose(arr.reshape(12, 3, 2), reshaped.toarray())
assert allclose(arr.reshape(12, 3, 2), original.reshape(12, 3, 2).toarray())
assert allclose(arr.reshape(36, 2), original.reshape(36, 2).toarray())
assert allclose(arr.reshape(4, 3, 3, 2), original.reshape(4, 3, 3, 2).toarray())

reshaped = original.reshape_keys(36)
assert allclose(arr.reshape(36, 2), reshaped.toarray())
# must conserve number of elements
with pytest.raises(ValueError):
original.reshape(6, 3, 2)

reshaped = original.reshape_keys(4, 3, 3)
assert allclose(arr.reshape(4, 3, 3, 2), reshaped.toarray())
# cannot change length of series
with pytest.raises(ValueError):
original.reshape(6, 3, 4)
17 changes: 11 additions & 6 deletions thunder/images/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,20 +235,25 @@ def squeeze(self):
axis = tuple(range(1, len(self.shape) - 1)) if prod(self.shape[1:]) == 1 else None
return self.map(lambda x: x.squeeze(axis=axis))

def reshape_values(self, *shape):
def reshape(self, *shape):
"""
Reshape images

Parameters
----------
shape: one or more ints
New shape of images
New shape
"""
if prod(self.value_shape) != prod(shape):
raise ValueError("Total number of elements in each image must be unchanged")
if prod(self.shape) != prod(shape):
raise ValueError("Reshaping must leave the number of elements unchanged")

newshape = (self.shape[0], ) + shape
return self._constructor(self.values.reshape(newshape)).__finalize__(self)
if self.shape[0] != shape[0]:
raise ValueError("Reshaping cannot change the number of images")

if len(shape) not in (3, 4):
raise ValueError("Reshaping must produce 2d or 3d images")

return self._constructor(self.values.reshape(shape)).__finalize__(self)

def max_projection(self, axis=2):
"""
Expand Down
35 changes: 18 additions & 17 deletions thunder/series/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,8 @@ def flatten(self):
"""
Reshape all dimensions but the last into a single dimension
"""
size = prod([s for i, s in enumerate(self.shape) if i in self.baseaxes])
newvalues = self.values.reshape(size, self.shape[-1])

if self.labels is not None:
fullshape = prod(self.labels.shape)
newlabels = self.labels.reshape(size, fullshape/size).squeeze()
else:
newlabels = None

return self._constructor(newvalues, labels=newlabels).__finalize__(self, noprop=('labels',))
size = prod(self.shape[:-1])
return self.reshape(size, self.shape[-1])

def count(self):
"""
Expand Down Expand Up @@ -256,20 +248,29 @@ def min(self):
"""
return self._constructor(self.values.min(axis=self.baseaxes, keepdims=True))

def reshape_keys(self, *shape):
def reshape(self, *shape):
"""
Reshape the keys of the time series
Reshape the Series object

Cannot change the last dimension.

Parameters
----------
shape: one or more ints
Shape of the new keys
New shape
"""
if prod(self.baseshape) != prod(shape):
raise ValueError("Total number of series elements must remain unchanged")
if prod(self.shape) != prod(shape):
raise ValueError("Reshaping must leave the number of elements unchanged")

if self.shape[-1] != shape[-1]:
raise ValueError("Reshaping cannot change the size of the constituent series (last dimension)")

if self.labels is not None:
newlabels = self.labels.reshape(*shape[:-1])
else:
newlabels = None

newshape = shape + (self.shape[-1], )
return self._constructor(self.values.reshape(newshape)).__finalize__(self)
return self._constructor(self.values.reshape(shape), labels=newlabels).__finalize__(self, noprop=('labels',))

def between(self, left, right):
"""
Expand Down