Python 获取groupby中的第一个和最后一个值

Python 获取groupby中的第一个和最后一个值,python,pandas,dataframe,group-by,pandas-groupby,Python,Pandas,Dataframe,Group By,Pandas 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

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
选择1


选项2-仅当索引唯一时有效
选项3-根据下面的说明,这仅在没有NAs时才有意义 我还滥用了
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


果然!第二个解决方案是采用第X列中的第一个有效值。现在强迫该值与索引a对齐是毫无意义的。

这可能是一个简单的解决方案

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) 请尝试以下方法:

对于最后一个值:
df.groupby('Column\u name').nth(-1)


对于第一个值:
df.groupby('Column_name').nth(0)

即使它看起来更复杂,
reset_index/agg
解决方案在有很多组的情况下也比
groupby/apply
解决方案快得多。例如,当
df=pd.DataFrame(np.random.randint(100,size=(10**3,4)),columns=list('ABCD')。设置索引(['A','B'])。重命名轴([None,None])
。很好的解决方案!可能还需要注意的是,
agg(['first','last'])
返回第一个和最后一个非NaN值(如果可用)<代码>应用(first_last)将返回第一个和最后一个值,即使它们是NaN。我认为对于最新的pandas版本,我们需要df.iloc而不是df.ix,请参见示例。
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])
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