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

DOC: Add unravel_index examples to np.arg[min|max|sort] #9333

Closed
wants to merge 5 commits into from
Closed

DOC: Add unravel_index examples to np.arg[min|max|sort] #9333

wants to merge 5 commits into from

Conversation

ElieGouzien
Copy link
Contributor

Hi,

Using np.arg[min|max|sort] for d-dimensional arrays whenever we want to work on the whole array, and retrieve indices is very unintuitive.
In #6078 some propositions were made to change that. But as a true modification seems not to be for tomorrow.
Here I propose a small add to the docstrings so that the user can understand by itself how to deal with it.

Élie

@@ -890,6 +890,13 @@ def argsort(a, axis=-1, kind='quicksort', order=None):
array([[0, 1],
[0, 1]])

Copy link
Member

Choose a reason for hiding this comment

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

Can you add a short description here to explain the example? That would also be appreciated in the other examples.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What about "Retrieving global sorting indices:" ?
I'm not native English speaker so don't hesitate to propose a reformulated version.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe: "Indices along each axis for sorting the flattened array"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Numpy superpowers come from the fact that the user can forget that he lives in a flat space, so I prefer avoiding a description of how it works to privilege what we get. See my new commit for my next intent (which is far from perfect).

@@ -890,6 +890,13 @@ def argsort(a, axis=-1, kind='quicksort', order=None):
array([[0, 1],
[0, 1]])

>>> np.unravel_index(np.argsort(x, axis=None), x.shape)
(array([0, 1, 1, 0]), array([0, 0, 1, 1]))
>>> x[np.unravel_index(np.argsort(x, axis=None), x.shape)]
Copy link
Member

Choose a reason for hiding this comment

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

I would probably stick to only the first line unless these additional examples show very different behavior -- space is at a premium in docstrings!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure about it.
You are write that only the first line give indication on how argsort works.
But do the average numpy user know about advanced indexing and argument packing?
I feel like retrieving the list of indices that sort the array elements is the most basic thing we want argsort to do.

Maybe removing the second line but keeping the last one is a good option since even without knowing advanced indexing anyone can make a loop from the last line and retrieve the second line.

@ElieGouzien
Copy link
Contributor Author

With "coordinates" instead of "indices" it now sounds good to me.

@eric-wieser
Copy link
Member

It was better before with indices in my opinion. "Coordinate" is a poor choice of word, especially since by convention the coordinate (x,y) is often at the index image[y,x]

@ElieGouzien
Copy link
Contributor Author

ElieGouzien commented Jun 30, 2017

That's exactly what my examples gives :
(x, y) such that a[x,y] = min(a)

For argsort it gives either:

  1. ([x1, x2, …, xk], [y1, y2, …, yk])
  2. [(x1, y1), (x2, y2), …, (xk, yk)]
    such that a[x1, y1] ≤ a[x2, y2] ≤ … ≤ a[xk, yk]

Maybe I should change the name of the array for argsort to avoid any confusion.

EDIT : the docstring of unravel_index is:

Converts a flat index or array of flat indices into a tuple of coordinate arrays.

@eric-wieser
Copy link
Member

eric-wieser commented Jun 30, 2017

I think you misread my message. My point was that coordinate can often refer to a reversed index - (x, y) vs arr[y, x] - this is why meshgrid has two different indexing modes.

However, I agree that it appearing in the docstring of unravel_index is an argument for this naming

@ElieGouzien
Copy link
Contributor Author

What I like with coordinate is that it's clearer that we have all the indices corresponding to each point.
And what about writing directly things like output : (x, y) such that a[x,y] == np.amin(a) ?

It seems that having a true option for recovering the min/max/sorting coordinates is again also asked there: #9283.

@charris charris changed the title New exemples for np.arg[min|max|sort]. DOC: New exemples for np.arg[min|max|sort]. Jul 1, 2017
@@ -890,6 +890,12 @@ def argsort(a, axis=-1, kind='quicksort', order=None):
array([[0, 1],
[0, 1]])

Coordinates of the sorted elements of a N-dimensional array:
Copy link
Contributor

Choose a reason for hiding this comment

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

Indices would be much more appropriate here, as per @eric-wieser's comment.

Copy link
Member

@eric-wieser eric-wieser left a comment

Choose a reason for hiding this comment

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

@ElieGouzien: Please change the documentation back to say indices. np.nonzero has exactly the same return value format, and refers to it as indices. We should be consistent here.

@ElieGouzien
Copy link
Contributor Author

@eric-wieser: I've applied your requested change.

@@ -952,6 +958,10 @@ def argmax(a, axis=None, out=None):
>>> np.argmax(a, axis=1)
array([2, 2])

Indices of the maximal elements of a N-dimensional array:
>>> np.unravel_index(np.argmax(a, axis=None), a.shape)
(1, 2)
Copy link
Member

Choose a reason for hiding this comment

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

Would be nice to show that the result of this can be used to index directly into a, and the same for the argsort example

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For sure, it's committed. Let me know if you like the way I've written it.

>>> from np.testing import assert_equal
>>> assert_equal(x[(array([0, 1, 1, 0]), array([0, 0, 1, 1]))], np.sort(x, axis=None))
>>> list(zip(*np.unravel_index(np.argsort(x, axis=None), x.shape)))
[(0, 0), (1, 0), (1, 1), (0, 1)]
Copy link
Member

Choose a reason for hiding this comment

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

This might be clearer as:

>>> ind = np.unravel_index(np.argsort(x, axis=None), x.shape)
>>> ind
(array([0, 1, 1, 0]), array([0, 0, 1, 1]))
>>> x[ind]  # same as np.sort(x, axis=None)
<whatever it is>

Repeating the call to unravel_index is obscuring the point, and assert_equal isn't that useful in docs. (we don't run doctests)

@eric-wieser eric-wieser changed the title DOC: New exemples for np.arg[min|max|sort]. DOC: Add unravel_index examples to np.arg[min|max|sort] Sep 22, 2017
@charris
Copy link
Member

charris commented Oct 5, 2017

Updated in #9826, so closing this. Thanks @ElieGouzien .

@charris charris closed this Oct 5, 2017
eric-wieser added a commit that referenced this pull request Oct 6, 2017
DOC: Add unravel_index examples to np.arg(min|max|sort)
@ElieGouzien ElieGouzien deleted the doc-arg--exemple branch October 14, 2017 12:33
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.

None yet

5 participants