Ich würde gerne wissen, ob es eine Möglichkeit gibt, alle negativen DataFrame-Zahlen durch Nullen zu ersetzen.
Antworten:
Wenn alle Ihre Spalten numerisch sind, können Sie die boolesche Indizierung verwenden:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame({'a': [0, -1, 2], 'b': [-3, 2, 1]})
In [3]: df
Out[3]:
a b
0 0 -3
1 -1 2
2 2 1
In [4]: df[df < 0] = 0
In [5]: df
Out[5]:
a b
0 0 0
1 0 2
2 2 1
Für den allgemeineren Fall zeigt diese Antwort die private Methode _get_numeric_data
:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame({'a': [0, -1, 2], 'b': [-3, 2, 1],
'c': ['foo', 'goo', 'bar']})
In [3]: df
Out[3]:
a b c
0 0 -3 foo
1 -1 2 goo
2 2 1 bar
In [4]: num = df._get_numeric_data()
In [5]: num[num < 0] = 0
In [6]: df
Out[6]:
a b c
0 0 0 foo
1 0 2 goo
2 2 1 bar
Mit timedelta
type scheint die boolesche Indizierung für separate Spalten zu funktionieren, jedoch nicht für den gesamten Datenrahmen. So können Sie tun:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame({'a': pd.to_timedelta([0, -1, 2], 'd'),
...: 'b': pd.to_timedelta([-3, 2, 1], 'd')})
In [3]: df
Out[3]:
a b
0 0 days -3 days
1 -1 days 2 days
2 2 days 1 days
In [4]: for k, v in df.iteritems():
...: v[v < 0] = 0
...:
In [5]: df
Out[5]:
a b
0 0 days 0 days
1 0 days 2 days
2 2 days 1 days
Update: Vergleich mit einem pd.Timedelta
funktioniert auf dem gesamten DataFrame:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame({'a': pd.to_timedelta([0, -1, 2], 'd'),
...: 'b': pd.to_timedelta([-3, 2, 1], 'd')})
In [3]: df[df < pd.Timedelta(0)] = 0
In [4]: df
Out[4]:
a b
0 0 days 0 days
1 0 days 2 days
2 2 days 1 days
Eine andere prägnante Methode hierfür ist pandas.DataFrame.clip .
Zum Beispiel:
import pandas as pd
In [20]: df = pd.DataFrame({'a': [-1, 100, -2]})
In [21]: df
Out[21]:
a
0 -1
1 100
2 -2
In [22]: df.clip(lower=0)
Out[22]:
a
0 0
1 100
2 0
Es gibt auch df.clip_lower(0)
.
clip
eine bestimmte Spalte bewerben möchten, können Sie wie df['col_name'] = df['col_name'].clip(lower=0)
Eine andere saubere Option, die ich als nützlich empfunden habe, ist pandas.DataFrame.mask, die "Werte ersetzt, bei denen die Bedingung erfüllt ist".
Erstellen Sie den DataFrame:
In [2]: import pandas as pd
In [3]: df = pd.DataFrame({'a': [0, -1, 2], 'b': [-3, 2, 1]})
In [4]: df
Out[4]:
a b
0 0 -3
1 -1 2
2 2 1
Ersetzen Sie negative Zahlen durch 0:
In [5]: df.mask(df < 0, 0)
Out[5]:
a b
0 0 0
1 0 2
2 2 1
Oder ersetzen Sie negative Zahlen durch NaN, die ich häufig benötige:
In [7]: df.mask(df < 0)
Out[7]:
a b
0 0.0 NaN
1 NaN 2.0
2 2.0 1.0
Wenn Sie mit einem großen df (40 mx 700 in meinem Fall) arbeiten, funktioniert es viel schneller und speicherfreundlicher durch Iteration von Spalten mit so etwas wie.
for col in df.columns:
df[col][df[col] < 0] = 0
num[num < 0] = 0