2015-12-25 10 views
6

Qualcuno può spiegarmi questo comportamento?Risultato imprevisto utilizzando l'indicizzazione .ix con elenco vs intervallo

import pandas as pd 

dates = pd.date_range('1/1/2000', periods=8) 
df = pd.DataFrame(np.random.randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D']) 

df.ix['2000-01-01':'2000-01-02', ['A', 'C']] 

## Output: 
        A   C 
2000-01-01 0.224944 -0.689382 
2000-01-02 -0.824735 -0.805512 

df.ix[['2000-01-01', '2000-01-02'], ['A', 'C']] 

## Output: 
      A C 
2000-01-01 NaN NaN 
2000-01-02 NaN NaN 

Mi aspettavo che entrambe le operazioni di indicizzazione restituiscano lo stesso (primo) risultato.

Poi ho sorta di ce l'ha:

from datetime import datetime 

df.loc[[datetime(2000, 1, 1), datetime(2000, 1, 5)], ['A','C']] 

## Output 
        A   C 
2000-01-01 0.224944 -0.689382 
2000-01-05 -0.393747 0.462126 

Ora, io non so la struttura interna di panda e perché si converte implicitamente stringhe date quando somministrato una serie, ma non quando somministrato una lista, ma il mio Immagino che un intervallo chiarisca che intendiamo un oggetto con natura ordinale, quindi i panda forse controllano l'indice, vedono che è un datetime e quindi analizzano le stringhe come date.

Ma poi la domanda diventa, perché fa la cosa giusta quando forniamo una singola stringa?

df.loc['2000-01-01', ['A','C']] 

## Output: 
A 0.224944 
C -0.689382 
Name: 2000-01-01 00:00:00, dtype: float64 

È un problema di prestazioni di non provare a convertire più valori quando viene fornito un elenco? Qualche altra decisione di progettazione?

+1

È ancora più semplice dimostrare il comportamento imprevisto: 'df.ix [['2000-01-01', '2000-01-02']]' - fornisce NaN – shx2

+1

@ shx2 Esattamente. E come hai sottolineato, fa la cosa giusta con una singola stringa di data. – kliron

+0

Sono abbastanza sicuro che si tratti di un bug noto ... ma nessuno vuole implementarlo (o almeno nessuno lo ha). Edit: non riesco a trovarlo su github ... ma penso che sia lì da qualche parte. –

risposta

1

L'accesso a DatetimeIndex con le stringhe è di tipo intrusato (poiché R fa questo è lì, ma è facile trovare alcuni casi limite come questo). Vale a dire:

  • funziona per le fette.
  • funziona per accesso singolo.
  • potrebbe funzionare per alcuni altri casi, ma non ci conterei.

E 'molto meglio usare Timestamps piuttosto che stringhe:

In [11]: df.ix[pd.Timestamp('2000-01-01'), ['A','C']] 
Out[11]: 
A 0.480959 
C 0.468689 
Name: 2000-01-01 00:00:00, dtype: float64 

In [12]: df.ix[pd.Timestamp('2000-01-01'):pd.Timestamp('2000-01-02'), ['A','C']] 
Out[12]: 
        A   C 
2000-01-01 0.480959 0.468689 
2000-01-02 -0.971965 -0.840954 

In [13]: df.ix[[pd.Timestamp('2000-01-01'), pd.Timestamp('2000-01-02')], ['A', 'C']] 
Out[13]: 
        A   C 
2000-01-01 0.480959 0.468689 
2000-01-02 -0.971965 -0.840954 

In [14]: df.ix[pd.to_datetime(['2000-01-01', '2000-01-02']), ['A', 'C']] 
Out[14]: 
        A   C 
2000-01-01 0.480959 0.468689 
2000-01-02 -0.971965 -0.840954 

Come menzionato nella sua risposta, questo è un po' più pulito (anche se non c'è ambiguità in questo caso) come .loc piuttosto di .ix.

Problemi correlati