Como obter as últimas N linhas de um DataFrame do pandas?

175

Eu tenho pandas dataframe df1e df2(df1 é vanila dataframe, df2 é indexado por 'STK_ID' e 'RPT_Date'):

>>> df1
    STK_ID  RPT_Date  TClose   sales  discount
0   000568  20060331    3.69   5.975       NaN
1   000568  20060630    9.14  10.143       NaN
2   000568  20060930    9.49  13.854       NaN
3   000568  20061231   15.84  19.262       NaN
4   000568  20070331   17.00   6.803       NaN
5   000568  20070630   26.31  12.940       NaN
6   000568  20070930   39.12  19.977       NaN
7   000568  20071231   45.94  29.269       NaN
8   000568  20080331   38.75  12.668       NaN
9   000568  20080630   30.09  21.102       NaN
10  000568  20080930   26.00  30.769       NaN

>>> df2
                 TClose   sales  discount  net_sales    cogs
STK_ID RPT_Date                                             
000568 20060331    3.69   5.975       NaN      5.975   2.591
       20060630    9.14  10.143       NaN     10.143   4.363
       20060930    9.49  13.854       NaN     13.854   5.901
       20061231   15.84  19.262       NaN     19.262   8.407
       20070331   17.00   6.803       NaN      6.803   2.815
       20070630   26.31  12.940       NaN     12.940   5.418
       20070930   39.12  19.977       NaN     19.977   8.452
       20071231   45.94  29.269       NaN     29.269  12.606
       20080331   38.75  12.668       NaN     12.668   3.958
       20080630   30.09  21.102       NaN     21.102   7.431

Eu posso obter as últimas 3 linhas do df2 por:

>>> df2.ix[-3:]
                 TClose   sales  discount  net_sales    cogs
STK_ID RPT_Date                                             
000568 20071231   45.94  29.269       NaN     29.269  12.606
       20080331   38.75  12.668       NaN     12.668   3.958
       20080630   30.09  21.102       NaN     21.102   7.431

enquanto df1.ix[-3:]fornece todas as linhas:

>>> df1.ix[-3:]
    STK_ID  RPT_Date  TClose   sales  discount
0   000568  20060331    3.69   5.975       NaN
1   000568  20060630    9.14  10.143       NaN
2   000568  20060930    9.49  13.854       NaN
3   000568  20061231   15.84  19.262       NaN
4   000568  20070331   17.00   6.803       NaN
5   000568  20070630   26.31  12.940       NaN
6   000568  20070930   39.12  19.977       NaN
7   000568  20071231   45.94  29.269       NaN
8   000568  20080331   38.75  12.668       NaN
9   000568  20080630   30.09  21.102       NaN
10  000568  20080930   26.00  30.769       NaN

Por quê ? Como obter as últimas 3 linhas de df1(dataframe sem índice)? Pandas 0.10.1

Grande erro
fonte
3
Você pode usar df[-3:]para produzir os resultados desejados. Isso foi tratado como um bug pelo WesM. Não tenho certeza se / quando ele está ficando fixo: stackoverflow.com/questions/14035817/...
Zelazny7
@ Zelazny7 Eu não acho isso certo. Eu acho que fatiar negativo ixfoi um erro, mas passar fatias negativas para __getitem__não é. df.iloc[-3:]delegar internamente para __getitem__com os mesmos argumentos, do df[-3:]é um atalho para df.iloc[-3:], não um bug.
cs95

Respostas:

394

Não esqueça DataFrame.tail! por exemplodf1.tail(10)

Wes McKinney
fonte
Eu fiz ... eu esqueci: o
Mike Rapadas
74

Isso se deve ao uso de índices inteiros ( ixseleciona aqueles por rótulo acima de -3 em vez de posição , e isso ocorre por design: veja a indexação de números inteiros nas "dicas" de pandas *).

* Nas versões mais recentes dos pandas, preferem loc ou iloc para remover a ambiguidade de ix como posição ou rótulo:

df.iloc[-3:]

veja os documentos .

Como Wes aponta, neste caso específico, você deve usar apenas o rabo!

Andy Hayden
fonte
1
@DavidWolever Não consigo reproduzir seu IndexError em 0.14.1, df.iloc [-5:] funciona bem para mim com seu exemplo. Qual versão do pandas você está usando?
Andy Hayden
10

Como obter as últimas N linhas de um DataFrame do pandas?

Se você está fatiando por posição, __getitem__(ou seja, fatiar com []) funciona bem e é a solução mais sucinta que encontrei para esse problema.

pd.__version__
# '0.24.2'

df = pd.DataFrame({'A': list('aaabbbbc'), 'B': np.arange(1, 9)})
df

   A  B
0  a  1
1  a  2
2  a  3
3  b  4
4  b  5
5  b  6
6  b  7
7  c  8

df[-3:]

   A  B
5  b  6
6  b  7
7  c  8

É o mesmo que chamar df.iloc[-3:], por exemplo ( ilocdelega internamente para __getitem__).


Como um aparte, se você deseja encontrar as últimas N linhas para cada grupo, use groupbye GroupBy.tail:

df.groupby('A').tail(2)

   A  B
1  a  2
2  a  3
5  b  6
6  b  7
7  c  8
cs95
fonte