10000 Fixed bug in numpy.piecewise() for 0-d array handling by ericsuh · Pull Request #331 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

Fixed bug in numpy.piecewise() for 0-d array handling #331

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 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 < 8000 /div>
Reverted numpy.piecewise() tests to original set with regression test
Fixed one bug in fix, changed unit tests of numpy.piecewise() to be the
original set except for the addition of one regression test.

Revisions of unit tests to include spelling out undocumented assumptions
of behavior of numpy.piecewise() will come later.
  • Loading branch information
ericsuh committed Mar 1, 2013
commit c7607340c6085f36db14b6329099f2384c93a639
3 changes: 2 additions & 1 deletion numpy/lib/function_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,8 @@ def piecewise(x, condlist, funclist, *args, **kw):
n2 = len(funclist)
if isscalar(condlist) or \
(isinstance(condlist, np.ndarray) and condlist.ndim == 0) or \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the behavior and needs to be documented. I've also looked at the following version:

    def isscalarlike(a):
        return isscalar(a) or (isinstance(a, np.ndarray) and a.ndim == 0)

    x = asanyarray(x)
    n2 = len(funclist)
    if isscalarlike(condlist) or (x.ndim > 0 and isscalarlike(condlist[0])):
        condlist = [condlist]

Which is a bit different again, but clearer I think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I suspect this change is probably fine but I haven't wrapped my head
around that complex conditional...

On Sun, Aug 18, 2013 at 5:01 PM, Charles Harris notifications@github.comwrote:

In numpy/lib/function_base.py:

@@ -674,20 +674,13 @@ def piecewise(x, condlist, funclist, _args, *_kw):
x = asanyarray(x)
n2 = len(funclist)
if isscalar(condlist) or \

  •       not (isinstance(condlist[0], list) or
    
  •            isinstance(condlist[0], ndarray)):
    
  •        (isinstance(condlist, np.ndarray) and condlist.ndim == 0) or \
    

This changes the behavior and needs to be documented. I've also looked at
the following version:

def isscalarlike(a):
    return isscalar(a) or (isinstance(a, np.ndarray) and a.ndim == 0)

x = asanyarray(x)
n2 = len(funclist)
if isscalarlike(condlist) or (x.ndim > 0 and isscalarlike(a[0])):
    condlist = [condlist]

Which is a bit different again, but clearer I think.


Reply to this email directly or view it on GitHubhttps://github.com//pull/331/files#r5831760
.

(x.ndim > 0 and condlist[0].ndim == 0):
(x.ndim > 0 and (isscalar(condlist[0]) or \
(isinstance(condlist, np.ndarray) and condlist[0].ndim == 0))):
condlist = [condlist]
condlist = [asarray(c, dtype=bool) for c in condlist]
n = len(condlist)
Expand Down
166 changes: 34 additions & 132 deletions numpy/lib/tests/test_function_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1179,150 +1179,52 @@ def test_simple(self):


class TestPiecewise(TestCase):
def test_0d(self):
# Input: scalar
x = 5

# Condition: scalar bool
y = piecewise(x, x < 7, [1])
assert(y.ndim == 0)
assert(y == 1)

# Condition: singleton list of scalar bool
y = piecewise(x, [x < 7], [1])
assert(y == 1)

# Condition: 0-d array of bool
y = piecewise(x, np.array(x < 7), [1])
assert(y == 1)

# Condition: 1-d array of bool
y = piecewise(x, np.array([x < 7]), [1])
assert(y == 1)

# Condition: singleton list of 0-d array of bool
y = piecewise(x, [np.array(x < 7)], [1])
assert(y == 1)

# Condition: singleton list of 1-d array of bool
y = piecewise(x, [np.array([x < 7])], [1])
assert(y == 1)

# Condition: scalar int
y = piecewise(x, 1, [1])
assert(y == 1)

# Condition: singleton list of int
y = piecewise(x, [1], [1])
assert(y == 1)

# Condition: 1-d list of bools
y = piecewise(x, [x < 7, x >= 7], [1, 2])
assert(y == 1)

# Condition: 1-d list of bools (test alternative)
y = piecewise(x, [x >= 7, x < 7], [1, 2])
assert(y == 2)

# Condition: 1-d list of 0-d arrays of bools
y = piecewise(x, [np.array(x < 7), np.array(x >= 7)], [1, 2])
assert(y == 1)

# Input: 0-d array
x = np.array(5)

y = piecewise(x, x < 7, [1])
assert(y.ndim == 0)
assert(y == 1)

def test_simple(self):
# Input: 1-d array
x = np.array([3,5])

# Condition: bare array of bool
y = piecewise(x, x < 7, [1])
assert_array_equal(y, [1, 1])
# Condition is single bool list
x = piecewise([0, 0], [True, False], [1])
assert_array_equal(x, [1, 0])

# Make sure callables are called
y = piecewise(x, x < 7, [(lambda x: -x)])
assert_array_equal(y, [-3, -5])
# List of conditions: single bool list
x = piecewise([0, 0], [[True, False]], [1])
assert_array_equal(x, [1, 0])

# Condition: singleton list of array of bool
y = piecewise(x, [x < 7], [1])
assert_array_equal(y, [1, 1])
# Conditions is single bool array
x = piecewise([0, 0], np.array([True, False]), [1])
assert_array_equal(x, [1, 0])

# Condition: (1,2) array of bool
y = piecewise(x, np.array([x < 7]), [1])
assert_array_equal(y, [1, 1])
# Condition is single int array
x = piecewise([0, 0], np.array([1, 0]), [1])
assert_array_equal(x, [1, 0])

# Condition: list of array of bool
y = piecewise(x, [x >= 4, x < 4], [1, 2])
assert_array_equal(y, [2, 1])
# List of conditions: int array
x = piecewise([0, 0], [np.array([1, 0])], [1])
assert_array_equal(x, [1, 0])

y = piecewise(x, [x > 7, x <= 7], [1, 2])
assert_array_equal(y, [2, 2])

y = piecewise(x, [x < 4, x >= 4], [1, 2])
assert_array_equal(y, [1, 2])
x = piecewise([0, 0], [[False, True]], [lambda x:-1])
assert_array_equal(x, [0, -1])

y = piecewise(x, np.array([x < 4, x >= 4]), [1, 2])
assert_array_equal(y, [1, 2])
x = piecewise([1, 2], [[True, False], [False, True]], [3, 4])
assert_array_equal(x, [3, 4])

def test_default(self):
# Input: scalar
x = 5
# No value specified for x[1], should be 0
x = piecewise([1, 2], [True, False], [2])
assert_array_equal(x, [2, 0])

# built-in no-match: 0
# Should set x[1] to 3
x = piecewise([1, 2], [True, False], [2, 3])
assert_array_equal(x, [2, 3])

# Condition: scalar bool
y = piecewise(x, x > 7, [1])
assert_array_equal(y, 0)

# Condition: scalar int
y = piecewise(x, 0, [1])
assert_array_equal(y, 0)

# custom no-match

y = piecewise(x, x < 7, [1, 2])
assert_array_equal(y, [1])

y = piecewise(x, x > 7, [1, 2])
assert_array_equal(y, [2])

# Condition: scalar int
y = piecewise(x, 0, [1, 2])
assert_array_equal(y, [2])

# Input: 1-d array
x = np.array([3,5])

# built-in no-match: 0

y = piecewise(x, x > 7, [1])
assert_array_equal(y, [0,0])

y = piecewise(x, x < 4, [1])
assert_array_equal(y, [1, 0])

# custom no-match

y = piecewise(x, x < 7, [1, 2])
assert_array_equal(y, [1, 1])

y = piecewise(x, x > 7, [1, 2])
assert_array_equal(y, [2, 2])

y = piecewise(x, x < 4, [1, 2])
assert_array_equal(y, [1, 2])

# Condition: list of array of bool
y = piecewise(x, [x < 4], [1, 2])
assert_array_equal(y, [1, 2])

# Condition: (1,2) array of bool
y = piecewise(x, np.array([x < 4]), [1, 2])
assert_array_equal(y, [1, 2])
def test_0d(self):
x = np.array(3)
y = piecewise(x, x > 3, [4, 0])
assert_(y.ndim == 0)
assert_(y == 0)

y = piecewise(x, [True, False], [1, 0])
assert_(y.ndim == 0)
assert_(y == 1)

class TestBincount(TestCase):
def test_simple(self):
Expand Down
0