удаление бесконечных значений из фреймов данных в панд?


каков самый быстрый / простой способ отбросить значения nan и inf/-inf из фрейма данных pandas без сброса mode.use_inf_as_null? Я хотел бы иметь возможность использовать subset и how доводы dropna, за исключением inf ценности, которые считаются пропавшими без вести, таких как:

df.dropna(subset=["col1", "col2"], how="all", with_inf=True)

это возможно? Есть ли способ сказать dropna включить inf в его определении пропущенных значений?

6 110

6 ответов:

самый простой способ-это сначала 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

тот же метод будет работать для серии.

вот еще один метод с помощью .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

с контекстом опции это возможно без постоянной установки use_inf_as_null. Например:

with pd.option_context('mode.use_inf_as_null', True):
    df = df.dropna(subset=['col1', 'col2'], how='all')

конечно, он может быть установлен для лечения inf как NaN постоянно с pd.set_option('use_inf_as_null', True) тоже.

вышеуказанное решение изменить infs, которые не находятся в целевых столбцах. Чтобы исправить это,

lst = [np.inf, -np.inf]
to_replace = dict((v, lst) for v in ['col1', 'col2'])
df.replace(to_replace, np.nan)

еще одним решением было бы использовать isin метод. Используйте его, чтобы определить, является ли каждое значение бесконечным или отсутствует, а затем цепочка all метод, чтобы определить, если все значения в строках бесконечны или отсутствует.

наконец, используйте отрицание этого результата, чтобы выбрать строки, которые не имеют всех бесконечных или отсутствующих значений с помощью логического индексирования.

all_inf_or_nan = df.isin([np.inf, -np.inf, np.nan]).all(axis='columns')
df[~all_inf_or_nan]

можно использовать 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