Comment obtenir les N dernières lignes d'un pandas DataFrame?

175

J'ai pandas dataframe df1et df2(df1 est vanila dataframe, df2 est indexé par 'STK_ID' et '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

Je peux obtenir les 3 dernières lignes de df2 par:

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

tout en df1.ix[-3:]donnant toutes les lignes:

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

Pourquoi ? Comment obtenir les 3 dernières lignes de df1(dataframe sans index)? Pandas 0.10.1

gros bug
la source
3
Vous pouvez utiliser df[-3:]pour produire les résultats souhaités. Cela a été résolu comme un bug par WesM. Je ne sais pas si / quand cela sera corrigé: stackoverflow.com/questions/14035817/…
Zelazny7
@ Zelazny7 Je ne pense pas que ce soit vrai. Je pense que le découpage négatif avec ixétait un bogue, mais passer des tranches négatives à __getitem__ne l'est pas. df.iloc[-3:]délègue en interne à __getitem__avec les mêmes arguments, do df[-3:]est un raccourci pour df.iloc[-3:], pas un bogue.
cs95

Réponses:

394

N'oubliez pas DataFrame.tail! par exempledf1.tail(10)

Wes McKinney
la source
J'ai fait ... j'ai oublié: o
Mike Rapadas
74

Ceci est dû à l'utilisation d'indices entiers ( ixsélectionne ceux par étiquette sur -3 plutôt que par position , et c'est par conception: voir l' indexation d'entiers dans pandas "gotchas" *).

* Dans les nouvelles versions des pandas, préférez loc ou iloc pour supprimer l'ambiguïté de ix comme position ou étiquette:

df.iloc[-3:]

voir la documentation .

Comme le souligne Wes, dans ce cas précis, vous devez simplement utiliser tail!

Andy Hayden
la source
1
@DavidWolever Je ne peux pas reproduire votre IndexError sur la 0.14.1, df.iloc [-5:] fonctionne très bien pour moi avec votre exemple. Quelle version de pandas utilisez-vous?
Andy Hayden
10

Comment obtenir les N dernières lignes d'un pandas DataFrame?

Si vous découpez par position, __getitem__(c'est-à-dire, découper avec []) fonctionne bien, et c'est la solution la plus succincte que j'ai trouvée pour ce problème.

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

Cela revient à appeler df.iloc[-3:], par exemple ( ilocdélégué en interne à __getitem__).


En passant, si vous voulez trouver les N dernières lignes de chaque groupe, utilisez groupbyet 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
la source