Переставить строки фрейма данных pandas на основе списка и сохранить порядок

#pandas #numpy

#pandas #numpy

Вопрос:

 import numpy as np 
import pandas as pd

df = pd.DataFrame(data={'result':[-6.77,6.11,5.67,-7.679,-0.0930,4.342]}
,index=['A','B','C','D','E','F'])
new_order = np.array([1,2,2,0,1,0])
  

Массив new_order numpy присваивает каждой строке одну из трех групп [0,1 или 2]. Я хотел бы переставить строки df так, чтобы сначала отображались эти строки в группе 0, затем 1 и, наконец, 2. В каждой из трех групп первоначальный порядок должен оставаться неизменным.

В начале df упорядочен следующим образом:

    result
A  -6.770
B   6.110
C   5.670
D  -7.679
E  -0.093
F   4.342
  

Вот желаемый результат с учетом приведенных выше входных данных.

    result
D  -7.679
F   4.342
A  -6.770
E  -0.093
B   6.110
C   5.670
  

Ответ №1:

Вы могли бы использовать argsort with kind='mergesort' для получения отсортированных индексов строк, которые сохраняют порядок, а затем просто индексировать в фрейм данных с теми, которые для желаемого результата, например —

 df.iloc[new_order.argsort(kind='mergesort')]
  

Пример запуска —

 In [2]: df
Out[2]: 
   result
A  -6.770
B   6.110
C   5.670
D  -7.679
E  -0.093
F   4.342

In [3]: df.iloc[new_order.argsort(kind='mergesort')]
Out[3]: 
   result
D  -7.679
F   4.342
A  -6.770
E  -0.093
B   6.110
C   5.670
  

Ответ №2:

чистые панды

 df.set_index(new_order, append=True) 
    .sort_index(level=1) 
    .reset_index(1, drop=True)
  

введите описание изображения здесь

объяснение

  • добавить new_order к индексу
    • set_index(new_order, append=True)
  • используйте этот новый уровень индекса и сортируйте по нему
    • sort_index(level=1)
  • удалите уровень индекса, который я добавил
    • reset_index(1, drop=True)

Комментарии:

1. На самом деле я не понимаю внутренних деталей этого, но протестировал, и это работает!

2. @Divakar надеюсь, это поможет

3. Итак, эта sort_index(level=1) часть сортируется таким образом, чтобы сохранить порядок?