2013-07-04 20 views
84

jaki jest najszybszy/najprostszy sposób na upuszczenie wartości nan i inf/-inf z pandy DataFrame bez resetowania mode.use_inf_as_null? Chciałbym, aby móc korzystać z subset i how argumenty dropna, z wyjątkiem inf wartości uznawanych brakuje, jak:upuszczając nieskończone wartości z ramek danych w pandach?

df.dropna(subset=["col1", "col2"], how="all", with_inf=True) 

jest to możliwe? Czy istnieje sposób, aby powiedzieć dropna, aby dołączyć inf do definicji brakujących wartości?

Odpowiedz

162

Najprostszym sposobem byłoby najpierw replace plików INF NaN:

df.replace([np.inf, -np.inf], np.nan) 

a następnie użyć dropna:

df.replace([np.inf, -np.inf], np.nan).dropna(subset=["col1", "col2"], how="all") 

Na przykład:

In [11]: df = pd.DataFrame([1, 2, np.inf, -np.inf]) 

In [12]: df.replace([np.inf, -np.inf], np.nan) 
Out[12]: 
    0 
0 1 
1 2 
2 NaN 
3 NaN 

Ta sama metoda będzie działać dla serii.

5

Powyższe rozwiązanie zmodyfikuje inf s, które nie znajdują się w kolumnach docelowych. Aby zaradzić tym,

lst = [np.inf, -np.inf] 
to_replace = dict((v, lst) for v in ['col1', 'col2']) 
df.replace(to_replace, np.nan) 
+2

python 2.7 i wyższe Ułatwienia wsparcie dict: '{v: LST dla vw cols}' –

10

Oto kolejny sposób korzystania .loc zastąpić inf z nan na Seria:

s.loc[(~np.isfinite(s)) & s.notnull()] = np.nan 

tak, to w odpowiedzi na oryginalne pytanie:

df = pd.DataFrame(np.ones((3, 3)), columns=list('ABC')) 

for i in range(3): 
    df.iat[i, i] = np.inf 

df 
      A   B   C 
0  inf 1.000000 1.000000 
1 1.000000  inf 1.000000 
2 1.000000 1.000000  inf 

df.sum() 
A inf 
B inf 
C inf 
dtype: float64 

df.apply(lambda s: s[np.isfinite(s)].dropna()).sum() 
A 2 
B 2 
C 2 
dtype: float64 
7

Z kontekst opcji, jest to możliwe bez stałego ustawienia use_inf_as_null. Na przykład:

with pd.option_context('mode.use_inf_as_null', True): 
    df = df.dropna(subset=['col1', 'col2'], how='all') 

Oczywiście można ją ustawić w leczeniu inf jak NaN trwale z pd.set_option('use_inf_as_null', True) też.

+1

Jest to odpowiedź najbardziej czytelny, a zatem jest najlepszy, mimo że jest niezgodny z literą (ale nie w duchu) oryginalne pytanie. – ijoseph

1

Jeszcze innym rozwiązaniem byłoby zastosowanie metody isin. Użyj go, aby określić, czy każda wartość jest nieskończona lub brakuje jej, a następnie łańcuch metody all, aby określić, czy wszystkie wartości w wierszach są nieskończone lub brakuje.

Wreszcie, użyj negacji tego wyniku, aby wybrać wiersze, które nie mają wszystkich nieskończonych lub brakujących wartości poprzez indeksowanie boolowskie.

all_inf_or_nan = df.isin([np.inf, -np.inf, np.nan]).all(axis='columns') 
df[~all_inf_or_nan] 
Powiązane problemy