Я хотел бы знать, есть ли способ заменить все отрицательные числа DataFrame нулями?
Как заменить отрицательные числа в Pandas Data Frame на ноль
Ответы (6)
Если все ваши столбцы числовые, вы можете использовать логическое индексирование:
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
Обновление: сравнение с 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
Другой краткий способ сделать это — 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)
.
clip
только к определенному столбцу, вы можете использовать df['col_name'] = df['col_name'].clip(lower=0)
.
- person gies0r; 04.10.2019
clip_lower
был устарел так что скорее придерживайтесь df.clip(lower=0)
- person Sally Levesque; 22.06.2020
Возможно, вы могли бы использовать pandas.where(args)
так:
data_frame = data_frame.where(data_frame < 0, 0)
Еще один чистый вариант, который я нашел полезным, — это 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
Замените отрицательные числа на 0:
In [5]: df.mask(df < 0, 0)
Out[5]:
a b
0 0 0
1 0 2
2 2 1
Или замените отрицательные числа на NaN, которые мне часто нужны:
In [7]: df.mask(df < 0)
Out[7]:
a b
0 0.0 NaN
1 NaN 2.0
2 2.0 1.0
С лямбда-функцией
df['column'] = df['column'].apply(lambda x : x if x > 0 else 0)
Если вы имеете дело с большим df (40 м x 700 в моем случае), он работает намного быстрее и экономит память за счет итерации по столбцам с чем-то вроде.
for col in df.columns:
df[col][df[col] < 0] = 0
num[num < 0] = 0
- person hlin117   schedule 19.02.2015