web-dev-qa-db-ja.com

列とインデックスの両方の値でpandas dataframe?

pandasデータフレームを列の値だけでなく、インデックスでもソートできますか?

列の値でpandasデータフレームを並べ替えると、結果のデータフレームを列で並べ替えることができますが、残念ながら、同じ値内でデータフレームのインデックスの順序が乱雑になりますソートされた列。

したがって、countという名前の列などの列でデータフレームを並べ替えることができますが、インデックスの値で並べ替えることもできますか?また、列を降順で並べ替えることも可能ですが、インデックスを昇順で並べ替えることはできますか?

データフレーム内の複数の列を並べ替える方法を知っています。また、最初にreset_index()インデックスを作成して並べ替えてから、インデックスを作成し直すことで、ここで求めていることを実現できます。しかし、それはより直感的で効率的な方法ですか?

33
Blaszard

Pandas 0.2最終的にあなたをそこに連れて行く:-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])
29
OmerB

[〜#〜] edit [〜#〜]pandas 0.23で直接行うことができます-OmerBを参照してください 回答


最も簡単な方法は、インデックスを列にコピーしてから、両方で並べ替えることです。

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

私はdf.sort(['count', 'index'])のようなこともできるようにしたいと思っていますが、もちろんそれはうまくいきません。

28
fantabolous

pandasバージョン0.22現在.

列をインデックスとして一時的に設定し、その列のインデックスをソートしてからリセットできます。デフォルトでは、既存のインデックスの順序を維持します。

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

上記は「インプレース」オプションで実行できると思いますが、上記のように読む方が簡単だと思います。

6
Iain D

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がグループ化されたレベルをインデックスの最初の位置に挿入するため、最後の行に「Location」をドロップします。それらをソートしてからドロップすると、ソートされた順序が保持されます。

1
delgadom

インデックスを昇順で維持しながら、列を降順に並べ替えるには:

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
1
cyborg

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

値とインデックスでソートすると、「SORTEDFRAME」ではなく「FRAMESORTED」になります

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

sort_indexascendingパラメーターをスカラーではなくリストとして渡す必要があることに注意してください。うまくいかないだろう。

1
Scott Boston