Skip to content

BUG: Fix double-wrapping of object scalars #8643

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

Merged
merged 1 commit into from
Apr 11, 2017

Conversation

eric-wieser
Copy link
Member

Fixes #8642

@eric-wieser
Copy link
Member Author

eric-wieser commented Feb 23, 2017

(since you reviewed and merged #8441)

@@ -134,9 +134,9 @@ def apply_along_axis(func1d, axis, arr, *args, **kwargs):
buff = res.__array_prepare__(buff)

# save the first result, then compute and save all remaining results
buff[ind0] = res
buff[ind0] = res[()]
Copy link
Member

Choose a reason for hiding this comment

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

I didn't realize that indexing like this was valid on non-scalar arrays. This needs a comment, or better yet, maybe a helper function. Something like asanyarray_or_scalar? This is related to #5353, though in this case we want fallback behavior.

Alternatively, maybe we should change indexing behavior for cases like this in general? I don't see any situation in which a user would want an object array of scalar object arrays.

Copy link
Member

Choose a reason for hiding this comment

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

Sure is possible, though you must be sure you have an array. Otherwise, object dtype might blow up in your face.

Copy link
Member Author

@eric-wieser eric-wieser Feb 23, 2017

Choose a reason for hiding this comment

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

I didn't realize that indexing like this was valid on non-scalar arrays

Yep, in these cases it's just a no-op, as if it were :, but repeated 0 times.

I'll add the comment

Copy link
Member Author

Choose a reason for hiding this comment

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

Perhaps asanyarray(or_scalar=True)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, comment added. I think that a helper function would be more widely applicable, so belongs in a separate MAINT PR. I've created #8681 to discuss what it should be named

@ahaldane
Copy link
Member

Tangent idea:

Maybe we should define a new helper method to convert 0d arrays to scalars. In C we have PyArray_Return to do this, which is used all over the place, demonstrating its usefulness.

I think the current workaround in python using empty tuples is a bit opaque, and there are weird edge cases involving it. See #7267, or this comment

@eric-wieser
Copy link
Member Author

eric-wieser commented Feb 28, 2017

This isn't quite the same problem as #7267, as here we know we have a 0d array and not a scalar. And that comment you link to is no longer applicable

@ahaldane
Copy link
Member

I agree #7267 is not a problem here, I should have said so more clearly.

I didn't realize that comment was no longer applicable... I guess empty tuple behavior changed pretty recently...

@eric-wieser
Copy link
Member Author

eric-wieser commented Feb 28, 2017

@ahaldane : Perhaps a regression in 1.12? I'm testing on 1.10.4, 1.11.1, and master, and all are fine

@ahaldane
Copy link
Member

Hmm maybe that comment was just wrong, I also don't notice any changes going back to 1.9.3.

for ind in inds:
buff[ind] = asanyarray(func1d(inarr_view[ind], *args, **kwargs))
buff[ind] = asanyarray(func1d(inarr_view[ind], *args, **kwargs))[()]
Copy link
Member Author

@eric-wieser eric-wieser Mar 6, 2017

Choose a reason for hiding this comment

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

This could also have been fixed by changing this line to buff[ind + np.index_exp[...]], and leaving the rest untouched. Probably better for not going through a scalar, and avoiding #7267?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, this is definitely the right approach, in light of #8902. Updating...

@eric-wieser eric-wieser force-pushed the fix-8642 branch 2 times, most recently from eb73409 to b3d7e69 Compare April 6, 2017 18:05
@eric-wieser
Copy link
Member Author

Adding this to the milestone, since it would be a shame to introduce a feature already broken

@mhvk
Copy link
Contributor

mhvk commented Apr 6, 2017

I wondered slightly about adding (slice(None),) instead of (Ellipsis,) but really it does not matter (and this way you may be ready for extening this to apply over multiple axis at the same time...

So, good to go as far as I'm concerned.

@eric-wieser
Copy link
Member Author

eric-wieser commented Apr 6, 2017

(slice(None),) would error when the operation is a reduction, as 3darray[1, 2, 3, :] is not valid, but 3darray[1, 2, 3, ...] is

Remember that these indices are used for input and output

@mhvk
Copy link
Contributor

mhvk commented Apr 6, 2017

Duh, should have seen that.

@eric-wieser
Copy link
Member Author

eric-wieser commented Apr 11, 2017

@shoyer, happy with the new implementation?

Digging a little deeper, the rules for object array nesting seem to be:

obj_array_0d = np.array(None)
obj_array = np.array([[1, 2], [3, 4]], object)
ind_producing_scalar = (0, 0)
ind_producing_0d = (0, 0, Ellipsis)

# nests object arrays
obj_array[ind_producing_scalar] = obj_array_0d

# does not nest object arrays
obj_array[ind_producing_0d] = obj_array_0d

I think these rules make sense, as they allow you to choose between nesting arrays and not doing so, although perhaps need more documentation elsewhere (but that's well out of scope for this PR).

Worth noting that obj_array[ind_producing_0d] is broken on masked arrays (#8684), but I've a fix for that in #8905, and we don't care about that in np.apply_along_axis till #8511 anyway.

Copy link
Member

@shoyer shoyer left a comment

Choose a reason for hiding this comment

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

This looks great to me. @eric-wieser please go ahead and merge!

@eric-wieser eric-wieser merged commit f368286 into numpy:master Apr 11, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants