2014-10-29 21 views
5

Mam pozornie łatwe zadanie. Dataframe z 2 kolumnami: A i B. Jeśli wartości w B są większe niż wartości w A - zastąp te wartości wartościami A. Zrobiłem to wykonując df.B[df.B > df.A] = df.A, jednak ostatnie uaktualnienie pand rozpoczęło się dając SettingWithCopyWarning kiedy spotkałem się z tym łańcuchem zadanie. Oficjalna dokumentacja zaleca używanie .loc.Zastąpienie wartości w kolumnie danych w oparciu o warunek

Okay, powiedziałem i zrobiłem to przez df.loc[df.B > df.A, 'B'] = df.A i wszystko działa dobrze, chyba że kolumna B ma wszystkie wartości NaN. Wtedy coś dziwnego się dzieje:

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 

Teraz, jeśli nawet jeden z elementów przez B spełnia warunek (większy niż), to wszystko działa poprawnie:

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 

Ale jeśli żaden z elementów śniadaniem spełniają wtedy wszystko NaN s get zastępuje z -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 

jest to błąd lub funkcja? Jak powinienem to zrobić?

Dziękujemy!

+1

Zdecydowanie wygląda na błąd, prawdopodobnie dobry pomysł, aby zgłosić się na [https://github.com/pydata/pandas/issues](https://github.com/pydata/pandas/issues) – Marius

Odpowiedz

7

To jest buggy, naprawiono here.

Ponieważ pandy pozwalają zasadniczo na wszystko, co ma być ustawione po prawej stronie wyrażenia w locie, prawdopodobnie istnieje 10+ przypadków, które wymagają ujednoznacznienia. Aby dać ci pomysł:

df.loc[lhs, column] = rhs 

gdzie prawa oś może być: list,array,scalar i lewa mogą być: slice,tuple,scalar,array

oraz niewielki podzbiór przypadków, gdy powstały dtype kolumny musi być wywnioskować/ustawić według do rhs. (To trochę skomplikowane). Na przykład powiedzmy, że nie ustawiłeś wszystkich elementów na LHS i był on liczbą całkowitą, musisz wymusić na float. Ale jeśli ustawiłeś wszystkie elementy ORAZ rhs był liczbą całkowitą, to trzeba ją przekonwertować BACK na liczbę całkowitą.

W tym konkretnym przypadku, LHS jest tablicą, więc my zwykle starają się zmusić LHS do rodzaju RHS, ale ta sprawa przeradza jeśli mamy niebezpieczną konwersję (int -> float)

Dość powiedzieć, że był to przypadek braku krawędzi.

Powiązane problemy