Ich glaube auch, dass Ihre zweite Zeile lauten solltenum[num < 0] = 0
hlin117
Antworten:
99
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
00-31-12221
In [4]: df[df < 0] = 0
In [5]: df
Out[5]:
a b
000102221
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
00-3 foo
1-12 goo
221 bar
In [4]: num = df._get_numeric_data()
In [5]: num[num < 0] = 0
In [6]: df
Out[6]:
a b c
000 foo
102 goo
221 bar
Mit timedeltatype 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
00 days -3 days
1-1 days 2 days
22 days 1 days
In [4]: for k, v in df.iteritems():
...: v[v < 0] = 0
...:
In [5]: df
Out[5]:
a b
00 days 0 days
10 days 2 days
22 days 1 days
Update: Vergleich mit einem pd.Timedeltafunktioniert 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
00 days 0 days
10 days 2 days
22 days 1 days
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.
num[num < 0] = 0
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
quelle
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)
.quelle
clip
eine bestimmte Spalte bewerben möchten, können Sie wiedf['col_name'] = df['col_name'].clip(lower=0)
clip_lower
wurde veraltet, also bleib lieber beidf.clip(lower=0)
Vielleicht könnten Sie
pandas.where(args)
so verwenden:data_frame = data_frame.where(data_frame < 0, 0)
quelle
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
quelle
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
quelle