@@ -949,34 +949,33 @@ def select_n_frame(frame, columns, n, method, keep):
949
949
columns = [columns ]
950
950
columns = list (columns )
951
951
ascending = method == 'nsmallest'
952
- index_is_unique = frame .index .is_unique
953
- if not index_is_unique :
954
- # If index not unique we must reset index to allow re-indexing below
955
- # We must save frame's index to tmp
956
- tmp = Series (np .arange (len (frame )), index = frame .index )
957
- frame = frame .reset_index (drop = True )
952
+ original_frame , original_index = frame , frame .index
953
+ frame .reset_index (drop = True , inplace = True )
958
954
for i , column in enumerate (columns ):
955
+ # For each column in columns we peform ``method`` on this frame
956
+ # To guard against the possibility ``method`` column has duplicate
957
+ # values that must be considered for futher columns (# GH15297) we
958
+ # filter using isin on the values returned by ``method``. If there are
959
+ # no duplicated values, we simply reindex like the values returned
960
+ # by ``method``, otherwise we sort the frame and continue
959
961
series = frame [column ]
960
962
values = getattr (series , method )(n , keep = keep )
961
963
if i + 1 == len (columns ):
964
+ # This is the last column => duplicates here don't matter
962
965
frame = frame .reindex (values .index )
963
966
else :
964
967
filtered_frame = frame [series .isin (values )]
965
968
if len (filtered_frame ) == len (values ):
966
969
# Values are unique in series => reindex and break
967
970
frame = frame .reindex (values .index )
968
971
break
972
+ # Values are not unique in series => sort and continue
969
973
frame = filtered_frame .sort_values (
970
974
column , ascending = ascending
971
975
)
972
- if not index_is_unique :
973
- # This below line of code is a little obfuscated. We are setting the
974
- # index of the frame back to it's original index using saved original
975
- # index stored in tmp. Because we reset the index on frame (above)
976
- # frame's index is now purely a unique integer index (as is tmp) =>
977
- # to restore the index to frame we can index tmp's index with frame's
978
- # index...
979
- frame .index = tmp .index [frame .index ]
976
+ original_frame .index = original_index # Restore the index
977
+ # Below we set the index of the returning frame to the original index
978
+ frame .index = original_index [frame .index ]
980
979
return frame
981
980
982
981
0 commit comments