Удаление бесконечных значений из данных в pandas?
каков самый быстрый/самый простой способ сбросить значения nan и inf/-inf из pandas DataFrame без сброса mode.use_inf_as_null
? Я хотел бы иметь возможность использовать аргументы subset
и how
dropna
, за исключением тех, которые считаются отсутствующими inf
, например:
df.dropna(subset=["col1", "col2"], how="all", with_inf=True)
Это возможно? Есть ли способ сказать dropna
включить inf
в определение отсутствующих значений?
Ответы
Ответ 1
Самый простой способ - сначала replace
infs to NaN:
df.replace([np.inf, -np.inf], np.nan)
а затем используйте dropna
:
df.replace([np.inf, -np.inf], np.nan).dropna(subset=["col1", "col2"], how="all")
Например:
In [11]: df = pd.DataFrame([1, 2, np.inf, -np.inf])
In [12]: df.replace([np.inf, -np.inf], np.nan)
Out[12]:
0
0 1
1 2
2 NaN
3 NaN
Тот же метод будет работать для серии.
Ответ 2
В контексте контекста это возможно без постоянной настройки use_inf_as_na
. Например:
with pd.option_context('mode.use_inf_as_na', True):
df = df.dropna(subset=['col1', 'col2'], how='all')
Конечно, можно настроить постоянную обработку inf
как NaN
с помощью
pd.set_option('use_inf_as_na', True)
Для более старых версий замените use_inf_as_na
на use_inf_as_null
.
Ответ 3
Вот еще один метод, использующий .loc
для замены inf на nan на Серии:
s.loc[(~np.isfinite(s)) & s.notnull()] = np.nan
Итак, в ответ на исходный вопрос:
df = pd.DataFrame(np.ones((3, 3)), columns=list('ABC'))
for i in range(3):
df.iat[i, i] = np.inf
df
A B C
0 inf 1.000000 1.000000
1 1.000000 inf 1.000000
2 1.000000 1.000000 inf
df.sum()
A inf
B inf
C inf
dtype: float64
df.apply(lambda s: s[np.isfinite(s)].dropna()).sum()
A 2
B 2
C 2
dtype: float64
Ответ 4
Приведенное выше решение изменит inf
, которого нет в целевых столбцах Чтобы исправить это,
lst = [np.inf, -np.inf]
to_replace = {v: lst for v in ['col1', 'col2']}
df.replace(to_replace, np.nan)
Ответ 5
Еще одно решение - использовать метод isin
. Используйте его, чтобы определить, является ли каждое значение бесконечным или отсутствующим, а затем связать метод all
, чтобы определить, являются ли все значения в строках бесконечными или отсутствуют.
Наконец, используйте отрицание этого результата, чтобы выбрать строки, которые не имеют всех бесконечных или отсутствующих значений с помощью булевской индексации.
all_inf_or_nan = df.isin([np.inf, -np.inf, np.nan]).all(axis='columns')
df[~all_inf_or_nan]
Ответ 6
Используйте (быстро и просто):
df = df[np.isfinite(df).all(1)]
Этот ответ основан на ответе Дугра на другой вопрос.
Вот пример кода:
import pandas as pd
import numpy as np
df=pd.DataFrame([1,2,3,np.nan,4,np.inf,5,-np.inf,6])
print('Input:\n',df,sep='')
df = df[np.isfinite(df).all(1)]
print('\nDropped:\n',df,sep='')
Результат:
Input:
0
0 1.0000
1 2.0000
2 3.0000
3 NaN
4 4.0000
5 inf
6 5.0000
7 -inf
8 6.0000
Dropped:
0
0 1.0
1 2.0
2 3.0
4 4.0
6 5.0
8 6.0
Ответ 7
Вы можете использовать pd.DataFrame.mask
с np.isinf
. Сначала вы должны убедиться, что все ваши серии данных имеют тип float
. Затем используйте dropna
со своей существующей логикой.
print(df)
col1 col2
0 -0.441406 inf
1 -0.321105 -inf
2 -0.412857 2.223047
3 -0.356610 2.513048
df = df.mask(np.isinf(df))
print(df)
col1 col2
0 -0.441406 NaN
1 -0.321105 NaN
2 -0.412857 2.223047
3 -0.356610 2.513048