Подтвердить что ты не робот

Сортировка pandas dataframe как по значениям столбца, так и по индексу?

Возможно ли сортировать фреймворк pandas по значениям столбца, но также по индексу?

Если вы сортируете фреймворк pandas по значениям столбца, вы можете получить результирующий фрейм данных, отсортированный по столбцу, но, к сожалению, вы видите порядок индексации вашего фрейма данных в одном значении отсортированного столбца.

Итак, могу ли я отсортировать фрейм данных по столбцу, например столбец с именем count, но и отсортировать его по значению индекса? И также возможно сортировать столбец по убыванию, но в то время как сортировать индекс по возрастанию?

Я знаю, как сортировать несколько столбцов в dataframe, а также знаю, что я могу достичь того, что я прошу здесь, первым индексом reset_index() и отсортировать его, а затем снова создать индекс. Но это более интуитивный и эффективный способ сделать это?

4b9b3361

Ответ 1

РЕДАКТИРОВАТЬ В pandas 0.23 вы можете просто сделать это напрямую - см. Ответ OmerB.


Рискну предположить, что самый простой способ - просто скопировать ваш индекс в столбец, а затем отсортировать по обоим.

df['colFromIndex'] = df.index
df = df.sort(['count', 'colFromIndex'])

Я также предпочел бы иметь возможность делать что-то вроде df.sort(['count', 'index']), но, конечно, это не работает.

Ответ 2

Панды 0.23, наконец, приводят вас туда: -D

Теперь вы можете передавать имена индексов (а не только имена столбцов) в качестве параметров для sort_values. Итак, этот однострочник работает:

df = df.sort_values(by = ['MyCol', 'MyIdx'], ascending = [False, True])

И если ваш индекс в настоящее время не назван:

df = df.rename_axis('MyIdx').sort_values(by = ['MyCol', 'MyIdx'], ascending = [False, True])

Ответ 3

Начиная с версии панд 0.22.

Вы можете временно установить столбец в качестве индекса, отсортировать индекс по этому столбцу и затем выполнить сброс. По умолчанию он будет поддерживать порядок существующего индекса:

df = df.set_index('column_name', append=True).sort_index(level=1).reset_index(level=1)

Я думаю, что вышеупомянутое могло бы быть сделано с опциями "на месте", но я думаю, что легче читать как выше.

Ответ 4

Чтобы отсортировать столбец по убыванию, сохраняя индекс вверх:

import pandas as pd
df = pd.DataFrame(index=range(5), data={'c': [4,2,2,4,2]})
df.index = df.index[::-1]
print df.sort(column='c', ascending=False)

Вывод:

   c
1  4
4  4
0  2
2  2
3  2

Ответ 5

Вы можете использовать комбинацию groupby и применять:

In [2]: df = pd.DataFrame({
            'transID':  range(8),
            'Location': ['New York','Chicago','New York','New York','Atlanta','Los Angeles',
                            'Chicago','Atlanta'],
            'Sales':    np.random.randint(0,10000,8)}).set_index('transID')
In [3]: df
Out[3]:
        Location    Sales
transID
0       New York    1082
1       Chicago     1664
2       New York    692
3       New York    5669
4       Atlanta     7715
5       Los Angeles 987
6       Chicago     4085
7       Atlanta     2927

In [4]: df.groupby('Location').apply(lambda d: d.sort()).reset_index('Location',drop=True)
Out[4]:
        Location    Sales
transID
4       Atlanta     7715
7       Atlanta     2927
1       Chicago     1664
6       Chicago     4085
5       Los Angeles 987
0       New York    1082
2       New York    692
3       New York    5669

Я отбрасываю "Местоположение" в последней строке, потому что groupby вставляет сгруппированные уровни в первые позиции индекса. Сортировка и последующее удаление сохраняют отсортированный порядок.

Ответ 6

Вы можете использовать восходящий параметр в sort_index, но вы должны передать его в виде списка, чтобы он работал правильно с pandas 0.22.0.

import pandas as pd
import numpy as np
df = pd.DataFrame({'idx_0':[2]*6+[1]*5,
                   'idx_1':[6,4,2,10,18,5,11,1,7,9,3],
                   'value_1':np.arange(11,0,-1),
                   'MyName':list('SORTEDFRAME')})

df = df.set_index(['idx_0','idx_1'])
df

Выход:

            MyName  value_1
idx_0 idx_1                
2     6          S       11
      4          O       10
      2          R        9
      10         T        8
      18         E        7
      5          D        6
1     11         F        5
      1          R        4
      7          A        3
      9          M        2
      3          E        1

Сортировка по значениям и индексу должна получить "FRAMESORTED" вместо "SORTEDFRAME"

df.sort_values('value_1', ascending=False)\
  .sort_index(level=0, ascending=[True])

Выход:

            MyName  value_1
idx_0 idx_1                
1     11         F        5
      1          R        4
      7          A        3
      9          M        2
      3          E        1
2     6          S       11
      4          O       10
      2          R        9
      10         T        8
      18         E        7
      5          D        6

Обратите внимание, что вы должны передавать ascending параметр в sort_index как список, а не как скаляр. Она не будет работать.

Ответ 7

Я считаю, что первоначальный порядок от sort_values сохраняется даже тогда, когда применяется sort_index, поэтому это должно работать:

df.sort_values('count', ascending=False).sort_index(level=[index_level1, index_level2])

Ответ 8

Я решаю эту проблему следующим образом:

df.to_csv('df.csv', index = False)
df = df.read_csv('df.csv')