2017-11-15 102 views
6

Opis

używam pandas.eval na logicznej serii z brakującymi danymi.pandas.eval z logicznej serii z brakującymi danymi

Aby to zrobić, używam indeksatora do oznaczania wartości innych niż null i .loc, aby zastosować tylko .eval w wierszach z danymi, których nie brakuje.

Zastosowanie operatora logicznego nie używającego wyrażenia ~bool lub not(bool) zwraca -1 lub -2.

Rozumiem, że to dlatego, że moja logiczna seria lanego jako typ obiektu z powodu brakujących wartości, ale zastanawiam się:

  • dlaczego -1 i -2 wyjście?
  • Jaki byłby właściwy sposób używania .eval w serii boolowskiej z brakującymi danymi?

Przykład

Oto przykład za pomocą powtarzalnych pandy 0.20.3.

df = pd.DataFrame({'bool': [True, False, None]}) 
    bool 
0 True 
1 False 
2 None 

indexer = ~pd.isnull(df['bool']) 
0  True 
1  True 
2 False 
Name: bool, dtype: bool 

df.loc[indexer].eval('~bool') 
0 -2 
1 -1 
Name: bool, dtype: object 
+0

Ale ciągle coraz Błąd wartości – Dark

+0

Dlaczego nie rzutować na wartość bool przed obliczeniem, np. 'Df.loc [indexer] .astype (bool) .eval ('~ bool')'. Też jestem ciekawy, dlaczego dostałeś -2 i -1 – Dark

+0

Nie mogę rzutować, ponieważ mogę mieć tam nie-boolowskie kolumny (eval dotyczy całej ramki danych, a nie tylko kolumny). na przykład Chcę być w stanie radzić sobie z 'df.eval ('~ bool & (num> 1)')' gdzie num jest kolumną numeryczną. – Alex

Odpowiedz

2

Dla eval, ~ mapy do op.invert jak seen in the source code here.

_unary_ops_syms = '+', '-', '~', 'not' 
_unary_ops_funcs = op.pos, op.neg, op.invert, op.invert 
_unary_ops_dict = dict(zip(_unary_ops_syms, _unary_ops_funcs)) 

Zatem gdy seria jest dobrej starej object typu, co widzisz tutaj jest

>>> ~True 
-2 
>>> ~False 
-1 

# or with your Series 
>>> ~pd.Series(True, dtype='object') 
0 -2 
dtype: object 

Jeżeli chcesz

>>> ~pd.Series(True) 
0 False 
dtype: bool 

Wyjścia ~True -> -2 i ~False -> -1 są ponieważ bool jest subc lass z int w języku Python, a -2, -1 są bitowym uzupełnieniem odpowiednio 1 i 0.


Oczywistym rozwiązaniem jest albo przekształcić szeregowo bool typu uprzednio z astype(bool) na dodatkowym SEtP, lub jeśli z jakiegoś powodu nie możesz zrobić przed eval,

>>> df.loc[indexer].eval('~bool.astype("bool")') 
0 False 
1  True 
Name: bool, dtype: bool