如何将Pandas Data Frame中的负数替换为零

Han*_*gon 46 python replace pandas

我想知道是否有一些用零替换所有DataFrame负数?

Lev*_*sky 75

如果所有列都是数字,则可以使用布尔索引:

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
Run Code Online (Sandbox Code Playgroud)

对于更一般的情况,这个答案显示了私有方法_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
Run Code Online (Sandbox Code Playgroud)

对于timedelta类型,布尔索引似乎在单独的列上工作,但不在整个数据帧上工作.所以你可以这样做:

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
Run Code Online (Sandbox Code Playgroud)

更新:pd.Timedelta整个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
Run Code Online (Sandbox Code Playgroud)


fol*_*oof 40

另一种简洁的方法是pandas.DataFrame.clip.

例如:

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
Run Code Online (Sandbox Code Playgroud)

还有df.clip_lower(0).

  • 如果您只想在特定列上应用“clip”,您可以像“df['col_name'] = df['col_name'].clip(lower=0)` (11认同)
  • `clip_lower` 已被[弃用](https://pandas.pydata.org/pandas-docs/version/0.24.2/reference/api/pandas.DataFrame.clip_lower.html),所以最好坚持使用 `df.clip(下=0)` (3认同)

Mic*_*lin 9

我发现另一个有用的干净选项是 pandas.DataFrame.mask,它将“替换条件为真的值”。

创建数据框:

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
Run Code Online (Sandbox Code Playgroud)

用 0 替换负数:

In [5]: df.mask(df < 0, 0)
Out[5]: 
   a  b
0  0  0
1  0  2
2  2  1

Run Code Online (Sandbox Code Playgroud)

或者,用 NaN 替换负数,这是我经常需要的:

In [7]: df.mask(df < 0)
Out[7]: 
     a    b
0  0.0  NaN
1  NaN  2.0
2  2.0  1.0
Run Code Online (Sandbox Code Playgroud)


aus*_*acy 8

也许你可以pandas.where(args)像这样使用:

data_frame = data_frame.where(data_frame < 0, 0)
Run Code Online (Sandbox Code Playgroud)


Viv*_*han 5

使用 lambda 函数

df['column'] = df['column'].apply(lambda x : x if x > 0 else 0)
Run Code Online (Sandbox Code Playgroud)