web-dev-qa-db-ja.com

groupbyの最初と最後の値を取得する

データフレームがありますdf

df = pd.DataFrame(np.arange(20).reshape(10, -1),
                  [['a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'd'],
                   ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']],
                  ['X', 'Y'])

インデックスの最初のレベルでグループ化された最初と最後の行を取得するにはどうすればよいですか?

私は試した

df.groupby(level=0).agg(['first', 'last']).stack()

そして得た

          X   Y
a first   0   1
  last    6   7
b first   8   9
  last   12  13
c first  14  15
  last   16  17
d first  18  19
  last   18  19

これは私が望むものにとても近いです。レベル1のインデックスを保持して、代わりにこれを取得するにはどうすればよいですか。

      X   Y
a a   0   1
  d   6   7
b e   8   9
  g  12  13
c h  14  15
  i  16  17
d j  18  19
  j  18  19
19
Brian

オプション1

_def first_last(df):
    return df.ix[[0, -1]]

df.groupby(level=0, group_keys=False).apply(first_last)
_

enter image description here


オプション2-インデックスが一意の場合にのみ機能します

_idx = df.index.to_series().groupby(level=0).agg(['first', 'last']).stack()
df.loc[idx]
_

オプション3-以下の注記に従って、これはNAがない場合にのみ意味があります

agg関数も悪用しました。以下のコードは機能しますが、はるかに醜いです。

_df.reset_index(1).groupby(level=0).agg(['first', 'last']).stack() \
    .set_index('level_1', append=True).reset_index(1, drop=True) \
    .rename_axis([None, None])
_

注意

@unutbuごと:agg(['first', 'last'])は最初のna以外の値を取ります。

私はこれを、列ごとに実行する必要があると解釈しました。さらに、インデックスレベル= 1を強制的に調整しても意味がありません。

別のテストを含めましょう

_df = pd.DataFrame(np.arange(20).reshape(10, -1),
                  [list('aaaabbbccd'),
                   list('abcdefghij')],
                  list('XY'))

df.loc[Tuple('aa'), 'X'] = np.nan
_

_def first_last(df):
    return df.ix[[0, -1]]

df.groupby(level=0, group_keys=False).apply(first_last)
_

enter image description here

_df.reset_index(1).groupby(level=0).agg(['first', 'last']).stack() \
    .set_index('level_1', append=True).reset_index(1, drop=True) \
    .rename_axis([None, None])
_

enter image description here

案の定!この2番目のソリューションは、列Xの最初の有効な値を取ります。その値をインデックスaに合わせるように強制することは無意味です。

15
piRSquared

これは簡単な解決策になるかもしれません。

df.groupby(level = 0, as_index= False).nth([0,-1])

      X   Y
a a   0   1
  d   6   7
b e   8   9
  g  12  13
c h  14  15
  i  16  17
d j  18  19

お役に立てれば。 (Y)

4
Akarsh Jain

これを試してください:

最後の値の場合:df.groupby('Column_name').nth(-1)

最初の値の場合:df.groupby('Column_name').nth(0)

0
nat23dip