web-dev-qa-db-ja.com

Pandasデータフレームの負の数をゼロで置き換える方法

DataFrameのすべての負の数値をゼロで置き換える方法があるかどうかを知りたいですか?

42
Hangon

すべての列が数値の場合、ブールインデックスを使用できます。

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

より一般的な場合、 この答え はプライベートメソッド_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

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

Update: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
66
Lev Levitsky

これを行う別の簡潔な方法は、 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

df.clip_lower(0)もあります。

35
follyroof

おそらく、次のようにpandas.where(args)を使用できます。

data_frame = data_frame.where(data_frame < 0, 0)
8
aus_lacy

大きなdf(私の場合は40m x 700)を処理している場合は、はるかに高速に動作し、列のようなものを繰り返し処理することでメモリに精通しています。

for col in df.columns:
    df[col][df[col] < 0] = 0
3
MarKo9