グループ内の最初と最後の値を取得する 質問する

グループ内の最初と最後の値を取得する 質問する

データフレームがある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'])

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

上記の入力から予想される出力:

      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

ベストアンサー1

オプション1

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

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

ここに画像の説明を入力してください


オプション 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)

ここに画像の説明を入力してください

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])

ここに画像の説明を入力してください

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

おすすめ記事