Repository: pandas-dev/pandas

Issue:
DOC: Series.nlargest sorts index with duplicates
I think the description of this method is incorrect. The effect of parameter "keep" says, if we pass "first" to it, means to take the first duplicate value, while we pass "last" to it, means to take the last duplicate value.
However, its real effect is to sort the duplicate values by their indexes.
Hope we put it right soon.
DOC: Series.nlargest sorts index with duplicates
I think the description of this method is incorrect. The effect of parameter "keep" says, if we pass "first" to it, means to take the first duplicate value, while we pass "last" to it, means to take the last duplicate value.
However, its real effect is to sort the duplicate values by their indexes.
Hope we put it right soon.


Discussion:
I don't think the docstring is wrong, but could be updated to note that the resulting index is sorted

```python
s = pd.Series([3, 3, 3, 2, 1], index=['a', 'b', 'c', 'd', 'e'])

s.nlargest(2, keep='first')
Out[27]: 
a    3
b    3
dtype: int64

s.nlargest(2, keep='last')
Out[28]: 
c    3
b    3
dtype: int64


# unsorted
s = pd.Series([3, 3, 3, 2, 1], index=['e', 'd', 'c', 'b', 'a'])
s.nlargest(2, keep='last')
Out[30]: 
c    3
d    3

```
can I try to fix it?
> can I try to fix it?

did you take the issue?
@chris-b1 I think the description for `keep` could be more clear. Currently it said:
```
            - ``first`` : take the first occurrences based on the index order
            - ``last`` : take the last occurrences based on the index order
```

The index order might not be the same as the order of the index of the Series if the Series is not ordered. 
For instance,
```python
# unsorted
s = pd.Series([3, 3, 3, 2, 1], index=['e', 'd', 'c', 'b', 'a'])
s.nlargest(2, keep='last')
Out[30]: 
c    3
d    3
```
I would naturally assume the index order for `keep='last'` would be `'d'` and `'e'` instead of `'c'` and `'d'` by thinking of ordering `index`. 
@thoo I think the description is correct insofar as it is order of the items in the index array. It's possible that it could be reworded to be a bit more clear like so:
```
            - ``first`` : return the first n occurrences in given index order
            - ``last`` : return the last n occurrences in reverse index order
```
@chris-b1 One thing that I noticed while looking into this is that when you call `s.nlargest(2,keep="last")` it doesn't return the items sorted by index, but in reverse order by index. For example:
```
>>>s = pd.Series([3, 1, 3, 2, 3,], index=['e', 'a', 'c', 'b', 'd'])
>>>s.nlargest(3, keep='last')
d    3
c    3
e    3
```
I feel as if this is a bug in it's own way and that it should instead be returning in the original index order i.e.
```
//should return
e    3
c    3
d    3
```
I don't think the docstring is wrong, but could be updated to note that the resulting index is sorted

```python
s = pd.Series([3, 3, 3, 2, 1], index=['a', 'b', 'c', 'd', 'e'])

s.nlargest(2, keep='first')
Out[27]: 
a    3
b    3
dtype: int64

s.nlargest(2, keep='last')
Out[28]: 
c    3
b    3
dtype: int64


# unsorted
s = pd.Series([3, 3, 3, 2, 1], index=['e', 'd', 'c', 'b', 'a'])
s.nlargest(2, keep='last')
Out[30]: 
c    3
d    3

```
can I try to fix it?
> can I try to fix it?

did you take the issue?
@chris-b1 I think the description for `keep` could be more clear. Currently it said:
```
            - ``first`` : take the first occurrences based on the index order
            - ``last`` : take the last occurrences based on the index order
```

The index order might not be the same as the order of the index of the Series if the Series is not ordered. 
For instance,
```python
# unsorted
s = pd.Series([3, 3, 3, 2, 1], index=['e', 'd', 'c', 'b', 'a'])
s.nlargest(2, keep='last')
Out[30]: 
c    3
d    3
```
I would naturally assume the index order for `keep='last'` would be `'d'` and `'e'` instead of `'c'` and `'d'` by thinking of ordering `index`. 
@thoo I think the description is correct insofar as it is order of the items in the index array. It's possible that it could be reworded to be a bit more clear like so:
```
            - ``first`` : return the first n occurrences in given index order
            - ``last`` : return the last n occurrences in reverse index order
```
@chris-b1 One thing that I noticed while looking into this is that when you call `s.nlargest(2,keep="last")` it doesn't return the items sorted by index, but in reverse order by index. For example:
```
>>>s = pd.Series([3, 1, 3, 2, 3,], index=['e', 'a', 'c', 'b', 'd'])
>>>s.nlargest(3, keep='last')
d    3
c    3
e    3
```
I feel as if this is a bug in it's own way and that it should instead be returning in the original index order i.e.
```
//should return
e    3
c    3
d    3
```

Resolving patch:
diff --git a/pandas/core/series.py b/pandas/core/series.py
--- a/pandas/core/series.py
+++ b/pandas/core/series.py
@@ -3098,8 +3098,10 @@ def nlargest(self, n=5, keep='first'):
             When there are duplicate values that cannot all fit in a
             Series of `n` elements:
 
-            - ``first`` : take the first occurrences based on the index order
-            - ``last`` : take the last occurrences based on the index order
+            - ``first`` : return the first `n` occurrences in order
+                of appearance.
+            - ``last`` : return the last `n` occurrences in reverse
+                order of appearance.
             - ``all`` : keep all occurrences. This can result in a Series of
                 size larger than `n`.
 
@@ -3194,8 +3196,10 @@ def nsmallest(self, n=5, keep='first'):
             When there are duplicate values that cannot all fit in a
             Series of `n` elements:
 
-            - ``first`` : take the first occurrences based on the index order
-            - ``last`` : take the last occurrences based on the index order
+            - ``first`` : return the first `n` occurrences in order
+                of appearance.
+            - ``last`` : return the last `n` occurrences in reverse
+                order of appearance.
             - ``all`` : keep all occurrences. This can result in a Series of
                 size larger than `n`.
 
@@ -3236,7 +3240,7 @@ def nsmallest(self, n=5, keep='first'):
         Monserat        5200
         dtype: int64
 
-        The `n` largest elements where ``n=5`` by default.
+        The `n` smallest elements where ``n=5`` by default.
 
         >>> s.nsmallest()
         Monserat      5200


Test patch: