Удаление бесконечных значений из данных в 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