Jak zdobyć ostatnie N rzędów pandy DataFrame?

175

Mam pandas dataframe df1i df2(df1 to vanila dataframe, df2 jest indeksowana przez „STK_ID” i „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

Mogę uzyskać ostatnie 3 rzędy df2 przez:

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

podczas gdy df1.ix[-3:]podaj wszystkie wiersze:

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

Czemu ? Jak uzyskać ostatnie 3 wiersze df1(dataframe bez indeksu)? Pandy 0.10.1

wielki robak
źródło
3
Możesz użyć, df[-3:]aby uzyskać pożądane wyniki. Zostało to rozwiązane jako błąd przez WesM. Nie jestem pewien, czy / kiedy to zostanie naprawione: stackoverflow.com/questions/14035817/ ...
Zelazny7
@ Zelazny7 Nie sądzę, że to prawda. Myślę, że ujemne wycinanie z ixbyło błędem, ale przekazywanie ujemnych plasterków do __getitem__nie jest. df.iloc[-3:]wewnętrznie deleguje do __getitem__z tymi samymi argumentami, do df[-3:]jest skrótem df.iloc[-3:], a nie błędem.
cs95

Odpowiedzi:

394

Nie zapomnij DataFrame.tail! na przykładdf1.tail(10)

Wes McKinney
źródło
Zrobiłem ... Zapomniałem: o
Mike Rapadas
74

Dzieje się tak z powodu używania indeksów całkowitych ( ixwybiera je na podstawie etykiety powyżej -3 zamiast pozycji , a jest to zgodne z projektem: patrz indeksowanie liczb całkowitych w pandach "problemy" *).

* W nowszych wersjach pandy wolą loc lub iloc, aby usunąć niejednoznaczność ix jako pozycji lub etykiety:

df.iloc[-3:]

zobacz dokumentację .

Jak zaznacza Wes, w tym konkretnym przypadku wystarczy użyć ogona!

Andy Hayden
źródło
1
@DavidWolever Nie mogę odtworzyć twojego IndexError na 0.14.1, df.iloc [-5:] działa dobrze dla mnie z twoim przykładem. Której wersji pand używasz?
Andy Hayden,
10

Jak zdobyć ostatnie N rzędów pandy DataFrame?

Jeśli krojenie według pozycji __getitem__(tj. Krojenie z []) działa dobrze i jest najbardziej zwięzłym rozwiązaniem tego problemu, jakie znalazłem.

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

To jest to samo, co df.iloc[-3:]na przykład wywołanie ( ilocwewnętrznie delegowani do __getitem__).


Na marginesie, jeśli chcesz znaleźć ostatnie N wierszy dla każdej grupy, użyj groupbyi 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
źródło