2016-06-03 17 views
5

Ero sconcertato perché non ho potuto modificare due colonne contemporaneamente usando .loc[:,['A', 'B'] che credo sia perché restituisce una copia invece di una vista. Non riesco a trovare in Indexing and Selecting Data una guida definitiva su quando restituisce una vista e quando restituisce una copia.L'assegnazione di .loc [:, ['A', 'B']] consente di cambiare il dtype delle colonne?

Sto usando pandas 0.18, posso vedere che nella versione precedente della documentazione (panda 0.13) era solito dire "Ogni volta che un array di etichette o un vettore booleano sono coinvolti nell'operazione di indicizzazione, il risultato sarà una copia", ma non riesco a trovare che nella documentazione corrente

pd.__version__ 
# u'0.18.0' 
df = pd.DataFrame({'A': ['1', '2', '3', '4', 
         '5', '6', '7', '8'], 
        'B': ['1', '2', '3', '4', 
         '5', '6', '7', '8'], 
        'C': ['1', '2', '3', '4', 
         '5', '6', '7', '8']}) 

df.dtypes 
    #A object 
    #B object 
    #C object 
    #dtype: object 

df2 = df.copy() 
df2[['A', 'B']] = df2.loc[:,['A' , 'B']].astype(float) # Works 
df2.dtypes 
    #A float64 
    #B float64 
    #C  object 
    #dtype: object 
df2 = df.copy() 
df2.loc[:,['A', 'B']] = df2.loc[:,['A' , 'B']].astype(float) # Does NOT work 
df2.dtypes 
    #A object 
    #B object 
    #C object 
    #dtype: object 

Nessuno di coloro che sollevano un avvertimento SettingWithCopy. Quindi sono un po 'confuso dal perché, l'assegnazione di df2.loc[:, ['A', 'B']] non ha alcun effetto.

A ben vedere Vedo che non è una copia dal momento che in un altro test, ho fatto assegnare una dataframe con valori diversi e mi furono "salvati" in df2, ma la la dtypes del df2 non può essere "set "tramite l'assegnazione .loc[:, ['A', 'B']].

C'è qualche motivo per cui l'assegnazione di .loc[:, ['A', 'B']] = non modifica i tipi e [['A', 'B']] =?

+0

Questo sembra un bug, il comportamento è lo stesso in '0.18.1' e il' dtypes' non è impostato correttamente, se si guarda 'df2 ['A']. Iloc [0]' si vedete che è effettivamente 'float' dtype come tutti gli elementi' df2 ['A']. apply (lambda x: print (type (x))) 'potrebbe essere che dal momento che stiamo usando i nuovi indicizzatori, sta prendendo un po 'di posizione che potrebbe non essere sicuro se tutte le righe sono state modificate in modo da preservare il dtype originale ma questa è un'ipotesi – EdChum

+0

Anche 'per c in [' A ',' B ']: df2.loc [:, c] = df2.loc [:, c] .astype (float) 'funziona, ma che assegna' pd.Series' uno per uno invece di tutto 'DataFrame' – ecerulm

risposta

4

In realtà sono stati aggiunti solo uno issue e doc note. Fondamentalmente, .loc tenta di tornare al dtype originale sul compito, dove non lo è il []. È il comportamento previsto, ma un po 'sottile.