it-swarm.com.de

unendliche Werte aus Datenrahmen in Pandas löschen?

was ist der schnellste/einfachste Weg, um nan und inf/-inf Werte von einem pandas= DataFrame ohne Zurücksetzen von mode.use_inf_as_null zu löschen? Ich möchte in der Lage sein, das subset und how Argumente von dropna, außer wenn inf Werte als fehlend angesehen werden, wie:

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

ist das möglich? Gibt es eine Möglichkeit, dropna anzuweisen, inf in die Definition fehlender Werte aufzunehmen?

170
user248237

Der einfachste Weg wäre, zuerst replace infs nach NaN zu senden:

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

und benutze dann das dropna :

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

Zum Beispiel:

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

Die gleiche Methode würde für eine Serie funktionieren.

315
Andy Hayden

Bei Optionskontext ist dies möglich, ohne use_inf_as_na Dauerhaft zu setzen. Zum Beispiel:

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

Natürlich kann eingestellt werden, dass inf als NaN permanent mit behandelt wird

pd.set_option('use_inf_as_na', True)

Ersetzen Sie bei älteren Versionen use_inf_as_na Durch use_inf_as_null.

19
ayhan

Hier ist eine andere Methode mit .loc um inf bei einer Serie durch nan zu ersetzen:

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

Also, als Antwort auf die ursprüngliche Frage:

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
15
Alexander

Die obige Lösung ändert die infs, die sich nicht in den Zielspalten befinden. Um dem abzuhelfen,

lst = [np.inf, -np.inf]
to_replace = {v: lst for v in ['col1', 'col2']}
df.replace(to_replace, np.nan)
7
has2k1

Eine weitere Lösung wäre die Verwendung der isin -Methode. Verwenden Sie diese Option, um festzustellen, ob jeder Wert unendlich ist oder fehlt, und verketten Sie dann die all -Methode, um festzustellen, ob alle Werte in den Zeilen unendlich sind oder fehlen.

Verwenden Sie schließlich die Negation dieses Ergebnisses, um die Zeilen mit nicht allen unendlichen oder fehlenden Werten über die Boolesche Indizierung auszuwählen.

all_inf_or_nan = df.isin([np.inf, -np.inf, np.nan]).all(axis='columns')
df[~all_inf_or_nan]
6
Ted Petrou

Verwenden Sie (schnell und einfach):

df = df[np.isfinite(df).all(1)]

Diese Antwort basiert auf DougRs Antwort in einer anderen Frage. Hier ein Beispielcode:

import pandas as pd
import numpy as np
df=pd.DataFrame([1,2,3,np.nan,4,np.inf,5,-np.inf,6])
print('Input:\n',df,sep='')
df = df[np.isfinite(df).all(1)]
print('\nDropped:\n',df,sep='')

Ergebnis:

Input:
    0
0  1.0000
1  2.0000
2  3.0000
3     NaN
4  4.0000
5     inf
6  5.0000
7    -inf
8  6.0000

Dropped:
     0
0  1.0
1  2.0
2  3.0
4  4.0
6  5.0
8  6.0
5
Markus Dutschke

Sie können pd.DataFrame.mask mit np.isinf . Sie sollten zunächst sicherstellen, dass Ihre Datenrahmenserien alle vom Typ float sind. Verwenden Sie dann dropna mit Ihrer vorhandenen Logik.

print(df)

       col1      col2
0 -0.441406       inf
1 -0.321105      -inf
2 -0.412857  2.223047
3 -0.356610  2.513048

df = df.mask(np.isinf(df))

print(df)

       col1      col2
0 -0.441406       NaN
1 -0.321105       NaN
2 -0.412857  2.223047
3 -0.356610  2.513048
2
jpp