2016-06-19 2 views
1

中レベルの最後の要素を取得する私は、この形式のデータフレームを持っています。はマルチインデックス

a b x 
1 1 31 
1 2 1 
1 3 42 
1 4 423 
1 5 42 
1 6 3 
1 7 44 
1 8 65437 
1 9 73 
2 1 5656 
2 2 7 
2 3 5 
2 4 5 
2 5 34 

abはインデックスされている、xが値です。

私は行1 9 732 5 34、つまりそのレベルの最後の行を取得したいと思います。

私は.loc,.iloc、および.xsを1時間つまずきましたが、動作させることができません。これはどうすればいいですか?

データフレームとして df
+0

'a'は常にソートされていますか? – Divakar

+0

@Divakar私の場合、はい。 – parchment

答えて

3

-

df.iloc[df.shape[0] - np.unique(df['a'][::-1],return_index=True)[1] - 1] 

サンプル実行:

print (df.groupby('a', as_index=False).last()) 
    a b x 
0 1 9 73 
1 2 5 34 

abMultiIndexのレベルであれば、最初の呼び出しreset_indexを:

print (df.reset_index().groupby('a', as_index=False).last()) 
    a b x 
0 1 9 73 
1 2 5 34 
2

と列aがすでにソートされているが、ここでのアプローチだ -

df[np.append(np.diff(df['a'])>0,True)] 

基本的な考え方は、私たちがソートされた列aに沿って分化を行い、(>0)との前向きな変化を探していることである与えますブール値の配列。ブール値配列の要素trueは、その列の「グループ」の終わりを示します。最後のグループの最後の要素に変更はないので、末尾のブール値の配列にTrue要素を追加する必要があります。最後に、dfにそのようなブール値配列を使用して行を選択し、希望の出力を与えます。

別のアプローチは、それぞれのグループの最初に出現する要素のインデックスを与えるオプションの引数return_indexを使用してnp.uniqueと示唆することができます。したがって、最後の要素で機能させるには、列aを反転してnp.uniqueを使用し、最初に出現するインデックスを取得してから、合計行数dfから減算します。最後に、dfのインデックスと最終出力のインデックスしたがって、実装は次のようになります - あなたはlastgroupbyを使用することができます

>>> df 
    a b x 
0 1 26 46 
1 1 17 32 
2 1 12 65 
3 1 31 96 
4 1 34 10 
5 1 7 80 
6 1 64 50 
7 1 0 34 
8 1 93 28 
9 2 18 92 
10 2 59 22 
11 2 87 31 
>>> df[np.append(np.diff(df['a'])>0,True)] 
    a b x 
8 1 93 28 
11 2 87 31 
>>> df.iloc[df.shape[0] - np.unique(df['a'][::-1],return_index=True)[1] - 1] 
    a b x 
8 1 93 28 
11 2 87 31 
+0

'np.diff'を使うのはいいアイデアです(+1)。他の問題にも使えますが、これはちょっと複雑すぎると思います。 – parchment

+0

'np.diff'は' a'のソートされた性質を使用します。だから、それについて自慢するパフォーマンスのビットで読みにくい:) – Divakar