2014-10-29 21 views
5

Ho un compito apparentemente facile. Dataframe con 2 colonne: A e B. Se i valori in B sono maggiori dei valori in A - sostituisci quei valori con i valori di A. Ho fatto questo facendo df.B[df.B > df.A] = df.A, tuttavia l'aggiornamento recente dei panda ha iniziato dando un SettingWithCopyWarning quando si incontrava questo incatenato assegnazione. La documentazione ufficiale raccomanda di utilizzare .loc.Sostituire i valori in una colonna dataframe in base alla condizione

OK, ho detto, e l'ho fatto tramite df.loc[df.B > df.A, 'B'] = df.A e tutto funziona correttamente, a meno che la colonna B non abbia tutti i valori di NaN. Poi succede qualcosa di strano:

In [1]: df = pd.DataFrame({'A': [1, 2, 3],'B': [np.NaN, np.NaN, np.NaN]}) 

In [2]: df 
Out[2]: 
    A B 
0 1 NaN 
1 2 NaN 
2 3 NaN 

In [3]: df.loc[df.B > df.A, 'B'] = df.A 

In [4]: df 
Out[4]: 
    A     B 
0 1 -9223372036854775808 
1 2 -9223372036854775808 
2 3 -9223372036854775808 

Ora, se anche uno solo degli elementi di B soddisfa la condizione (più grande di A), poi tutto funziona bene:

In [1]: df = pd.DataFrame({'A': [1, 2, 3],'B': [np.NaN, 4, np.NaN]}) 

In [2]: df 
Out[2]: 
    A B 
0 1 NaN 
1 2 4 
2 3 NaN 

In [3]: df.loc[df.B > df.A, 'B'] = df.A 

In [4]: df 
Out[4]: 
    A B 
0 1 NaN 
1 2 2 
2 3 NaN 

Ma se nessuno degli elementi B soddisfa, allora tutti NaN s get sostituisce con -9223372036854775808:

In [1]: df = pd.DataFrame({'A':[1,2,3],'B':[np.NaN,1,np.NaN]}) 

In [2]: df 
Out[2]: 
    A B 
0 1 NaN 
1 2 1 
2 3 NaN 

In [3]: df.loc[df.B > df.A, 'B'] = df.A 

In [4]: df 
Out[4]: 
    A     B 
0 1 -9223372036854775808 
1 2     1 
2 3 -9223372036854775808 

Si tratta di un bug o una funzione? Come dovrei aver fatto questa sostituzione?

Grazie!

+1

Sicuramente sembra un bug per me, probabilmente è una buona idea segnalare in [https://github.com/pydata/pandas/issues](http://github.com/pydata/pandas/issues) – Marius

risposta

7

Questo è un buggie, risolto here.

Poiché i panda consentono praticamente di impostare qualsiasi cosa sul lato destro di un'espressione in loc, ci sono probabilmente 10+ casi che devono essere disambiguati. Per darvi un'idea:

df.loc[lhs, column] = rhs 

dove dx potrebbero essere: list,array,scalar, e LHS potrebbero essere: slice,tuple,scalar,array

e un piccolo sottoinsieme di casi in cui la DTYPE risultante della colonna deve essere dedotto/set base al rhs. (Questo è un po 'complicato). Ad esempio, supponi di non impostare tutti gli elementi su lhs ed era intero, quindi devi forzare a fluttuare. Ma se hai impostato tutti gli elementi E il rh era un numero intero, allora ha bisogno di essere forzato da BACK a intero.

In questo caso particolare, i sx è un array, così ci sarebbe normalmente cercare di costringere gli ss al tipo di membro di destra, ma questo caso degenera se abbiamo una conversione non sicura (int -> float)

Basti dire che questo era un caso limite mancante.

Problemi correlati