pandalardaki veri çerçevelerinden sonsuz değerler düşüyor mu?


220

Bir panda DataFrame'den nan ve inf / -inf değerlerini sıfırlamadan düşürmenin en hızlı / basit yolu mode.use_inf_as_nullnedir? Kayıp değer olarak kabul edilen değerler dışında subsetve howargümanlarını kullanmak istiyorum:dropnainf

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

Mümkün mü? Eksik değerleri tanımına dropnaeklemeyi söylemenin bir yolu var mı inf?

Yanıtlar:


418

En basit yol replaceNaN'ye ilk infs yapmak olacaktır :

df.replace([np.inf, -np.inf], np.nan)

ve sonra şunu kullanın dropna:

df.replace([np.inf, -np.inf], np.nan).dropna(subset=["col1", "col2"], how="all")

Örneğin:

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

Aynı yöntem bir Seri için de işe yarar.


2
Nasıl bir "değişim" infdeğerler önceden etmek intgibi 0, belli bir sütuna?
3kstc

4
@ 3kstc kullanın .replace(..., 0). Sadece sütunlarda yapmak için bu sütunları güncellersinizdf[cols] = df[cols].replace(..., 0)
Andy Hayden

3
Belki replaceyerinde çalışmadığını belirtmeye değer , bu yüzden yeni DataFramebir iade
Marco

36

Seçenek bağlamında, bu kalıcı olarak ayarlanmadan mümkündür use_inf_as_na. Örneğin:

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

Tabii ki kalıcı infolarak tedavi etmek için ayarlanabilirNaN

pd.set_option('use_inf_as_na', True)

Eski sürümler için yerine use_inf_as_nabirlikte use_inf_as_null.


6
Bu en okunabilir cevaptır ve sonuç olarak orijinal soruyu harfle (ancak ruh olarak değil) ihlal etmesine rağmen en iyisidir.
ijoseph

2
(En azından) 0.24'ten itibaren pandalar use_inf_as_nullkaldırıldı ve gelecekteki bir sürümde kaldırılacak. use_inf_as_naBunun yerine kullanın . Cevaba ekle / güncelle?
Håkon T.

1
Bu inf, operasyonel seviye yerine küresel ayar seviyelerinde null olarak davranmak için daha iyi bir seçimdir . Bu, potansiyel olarak önce değerleri çarpıtmak için zaman tasarrufu sağlayabilir.
TaoPR

15

.locBir dizide inf'yi nan ile değiştirmek için kullanılan başka bir yöntem :

s.loc[(~np.isfinite(s)) & s.notnull()] = np.nan

Yani, orijinal soruya cevap olarak:

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

11

Kullanımı (hızlı ve basit):

df = df[np.isfinite(df).all(1)]

Bu cevap DougR'un başka bir sorudaki cevabına dayanmaktadır . İşte bir örnek kod:

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='')

Sonuç:

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

Yine başka bir çözüm isinyöntemi kullanmak olacaktır . Her değerin sonsuz veya eksik olup olmadığını belirlemek için kullanın ve ardından allsatırlardaki tüm değerlerin sonsuz veya eksik olup olmadığını belirlemek için yöntemi zincirleyin .

Son olarak, boole dizinleme yoluyla tüm sonsuz veya eksik değerlere sahip olmayan satırları seçmek için bu sonucun olumsuzlanmasını kullanın.

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

7

Yukarıdaki çözüm inf, hedef sütunlarda olmayanları değiştirecektir . Bunu düzeltmek için,

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

3
python 2.7 ve daha yüksek destek dict kavramaları anlama:{v: lst for v in cols}
Aryeh Leib Taurog

4

Sen kullanabilirsiniz pd.DataFrame.maskile np.isinf. Önce veri çerçevesi serilerinizin türünün olduğundan emin olmalısınız float. Ardından dropnamevcut mantığınızla kullanın .

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.