Ответ 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])
Примечание
per @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])
Конечно же! Это второе решение принимает первое допустимое значение в столбце X. Теперь бессмысленно заставить это значение выровняться с индексом a.