Belirli bir sütundaki değeri NaN olan Pandas DataFrame satırları nasıl bırakılır


753

Ben bu var DataFrameve sadece EPSsütun olmayan kayıtları istiyorum NaN:

>>> df
                 STK_ID  EPS  cash
STK_ID RPT_Date                   
601166 20111231  601166  NaN   NaN
600036 20111231  600036  NaN    12
600016 20111231  600016  4.3   NaN
601009 20111231  601009  NaN   NaN
601939 20111231  601939  2.5   NaN
000001 20111231  000001  NaN   NaN

... yani df.drop(....)elde edilen veri çerçevesini almak gibi bir şey :

                  STK_ID  EPS  cash
STK_ID RPT_Date                   
600016 20111231  600016  4.3   NaN
601939 20111231  601939  2.5   NaN

Bunu nasıl yaparım?



176
df.dropna(subset = ['column1_name', 'column2_name', 'column3_name'])
osa

Yanıtlar:


655

Düşmeyin, EPS'nin NA olmadığı satırları alın:

df = df[df['EPS'].notna()]

470
Bunun pandas.notnullyerine kullanmanızı tavsiye ederimnp.isfinite
Wes McKinney

11
Bırakma üzerine dizin oluşturma ve kopyalama yapmanın herhangi bir avantajı var mı?
Robert Muil

9
Hata oluşturur: TypeError: ufunc 'isfinite' giriş türleri için desteklenmiyor ve girişler '' safe '' döküm kuralına göre desteklenen herhangi bir türe güvenli bir şekilde zorlanamadı
Philipp Schwarz

4
@ wes-mckinney dropna () bu durumda pandas.notnull yerine daha iyi bir seçim olup olmadığını bana bildirebilir mi? Eğer öyleyse, neden?
stormfield

4
@PhilippSchwarz Bu hata, sütun ( EPSörnekte) tarafından sindirilemeyen dizeler veya başka türler içeriyorsa oluşur np.isfinite(). Bunu pandas.notnull()daha cömertçe ele alacak şekilde kullanmanızı tavsiye ederim .
normanius

902

Bu soru zaten çözüldü, ama ...

... Wouter'un orijinal yorumunda önerilen çözümü de düşünün . Eksik verileri işleme yeteneği dropna(), pandalara açıkça yerleştirilmiştir. Manuel olarak yapılmasına kıyasla potansiyel olarak geliştirilmiş performansın yanı sıra, bu işlevler de yararlı olabilecek çeşitli seçeneklerle birlikte gelir.

In [24]: df = pd.DataFrame(np.random.randn(10,3))

In [25]: df.iloc[::2,0] = np.nan; df.iloc[::4,1] = np.nan; df.iloc[::3,2] = np.nan;

In [26]: df
Out[26]:
          0         1         2
0       NaN       NaN       NaN
1  2.677677 -1.466923 -0.750366
2       NaN  0.798002 -0.906038
3  0.672201  0.964789       NaN
4       NaN       NaN  0.050742
5 -1.250970  0.030561 -2.678622
6       NaN  1.036043       NaN
7  0.049896 -0.308003  0.823295
8       NaN       NaN  0.637482
9 -0.310130  0.078891       NaN

In [27]: df.dropna()     #drop all rows that have any NaN values
Out[27]:
          0         1         2
1  2.677677 -1.466923 -0.750366
5 -1.250970  0.030561 -2.678622
7  0.049896 -0.308003  0.823295

In [28]: df.dropna(how='all')     #drop only if ALL columns are NaN
Out[28]:
          0         1         2
1  2.677677 -1.466923 -0.750366
2       NaN  0.798002 -0.906038
3  0.672201  0.964789       NaN
4       NaN       NaN  0.050742
5 -1.250970  0.030561 -2.678622
6       NaN  1.036043       NaN
7  0.049896 -0.308003  0.823295
8       NaN       NaN  0.637482
9 -0.310130  0.078891       NaN

In [29]: df.dropna(thresh=2)   #Drop row if it does not have at least two values that are **not** NaN
Out[29]:
          0         1         2
1  2.677677 -1.466923 -0.750366
2       NaN  0.798002 -0.906038
3  0.672201  0.964789       NaN
5 -1.250970  0.030561 -2.678622
7  0.049896 -0.308003  0.823295
9 -0.310130  0.078891       NaN

In [30]: df.dropna(subset=[1])   #Drop only if NaN in specific column (as asked in the question)
Out[30]:
          0         1         2
1  2.677677 -1.466923 -0.750366
2       NaN  0.798002 -0.906038
3  0.672201  0.964789       NaN
5 -1.250970  0.030561 -2.678622
6       NaN  1.036043       NaN
7  0.049896 -0.308003  0.823295
9 -0.310130  0.078891       NaN

Ayrıca, satırlar yerine sütunları bırakmak da dahil olmak üzere başka seçenekler de bulunmaktadır ( http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html adresindeki dokümanlara bakın ).

Oldukça kullanışlı!


282
kullanabilirsiniz df.dropna(subset = ['column_name']). Umarım en az bir kişiyi 'yanlış olan ne yapıyorum' ekstra 5 saniyesini kurtarır. Harika cevap, +1
James Tobin

10
@JamesTobin, bunun için bir işlev yazmak için sadece 20 dakika geçirdim! Resmi belgeler çok şifreli: "Dikkate alınması gereken diğer eksen boyunca etiketler, örneğin satırları bırakıyorsanız bunlar dahil edilecek sütunların bir listesi olacaktır". Ne anlama geldiklerini anlayamadım ...
osa

df.dropna(subset = ['column_name'])tam olarak aradığım şey! Teşekkürler!
amalik2205

123

Bunun zaten cevaplandığını biliyorum, ama sadece Aman'ın (bu harikaydı) genel açıklamasının aksine bu özel soruya tamamen panda çözümü için ve başka birinin bunun üzerine olması durumunda:

import pandas as pd
df = df[pd.notnull(df['EPS'])]

10
Aslında, özel cevap şu olurdu: df.dropna(subset=['EPS'])(Aman'ın genel açıklamasına dayanarak, elbette bu da işe yarıyor)
joris

2
notnullWes'in (Pandaların yazarı) başka bir cevaba yaptığı yorumda da önerdiği şeydir.
harika

Bu belki bir soru. Ama bir df [pd.notnull (...) veya df.dropna yaptığımda dizin düşüyor. Satır-endeksinde 10 boş değer uzunluğu 200 bir df içinde olsaydı Yani damla işlevini çalıştırdıktan sonra dataframe 1'den Neyse "yeniden endeksi" kendisine 9'a ve sonra 11 ila 200 endeksi değerlerine sahip
Aakash Gupta

Ayrıca ad bilmiyorsanız numaralı sütun df[pd.notnull(df[df.columns[INDEX]])]nerede INDEXolurdu
ocean800

60

Bunu kullanabilirsiniz:

df.dropna(subset=['EPS'], how='all', inplace=True)

18
how='all'Her iki yüzden dataframe yalnızca bir alan subsetting çünkü gereksiz burada 'all've 'any'aynı etkiye sahip olacaktır.
Anton Protopopov

35

Tüm çözümlerden en basitleri:

filtered_df = df[df['EPS'].notnull()]

Yukarıdaki çözüm np.isfinite () kullanmaktan daha iyidir


22

Dataframe yöntemini null veya ters isnull veya numpy.isnan kullanabilirsiniz :

In [332]: df[df.EPS.notnull()]
Out[332]:
   STK_ID  RPT_Date  STK_ID.1  EPS  cash
2  600016  20111231    600016  4.3   NaN
4  601939  20111231    601939  2.5   NaN


In [334]: df[~df.EPS.isnull()]
Out[334]:
   STK_ID  RPT_Date  STK_ID.1  EPS  cash
2  600016  20111231    600016  4.3   NaN
4  601939  20111231    601939  2.5   NaN


In [347]: df[~np.isnan(df.EPS)]
Out[347]:
   STK_ID  RPT_Date  STK_ID.1  EPS  cash
2  600016  20111231    600016  4.3   NaN
4  601939  20111231    601939  2.5   NaN


10

şu gerçeği kullanan başka bir çözüm np.nan != np.nan:

In [149]: df.query("EPS == EPS")
Out[149]:
                 STK_ID  EPS  cash
STK_ID RPT_Date
600016 20111231  600016  4.3   NaN
601939 20111231  601939  2.5   NaN

2

Başka bir sürüm:

df[~df['EPS'].isna()]

Bunu neden kullanmalıyım Series.notna()?
AMC

2

Çok sayıda sütuna sahip veri kümelerinde, kaç sütun boş değer içerdiğini ve kaç sütunun bulunmadığını görmek daha da iyidir.

print("No. of columns containing null values")
print(len(df.columns[df.isna().any()]))

print("No. of columns not containing null values")
print(len(df.columns[df.notna().all()]))

print("Total no. of columns in the dataframe")
print(len(df.columns))

Örneğin, veri çerçevemde, 19'u en az bir boş değer içeren 82 sütun içeriyordu.

Ayrıca , daha fazla boş değere sahip olanlara bağlı olarak sütunları ve satırları otomatik olarak kaldırabilirsiniz.
Bunu akıllıca yapan kod aşağıdadır:

df = df.drop(df.columns[df.isna().sum()>len(df.columns)],axis = 1)
df = df.dropna(axis = 0).reset_index(drop=True)

Not: Yukarıdaki kod, tüm null değerlerinizi kaldırır. Boş değerler istiyorsanız, bunları daha önce işleyin.


Başka Bir Soru Bağlantısı
Pradeep Singh

0

O eklenebilir '&' ek koşullar eklemek için kullanılabilir, örn.

df = df[(df.EPS > 2.0) & (df.EPS <4.0)]

İfadeleri değerlendirirken pandaların parantez gerektirdiğine dikkat edin.


2
Üzgünüm, ama OP baţka birţey istiyor. Btw, kodun yanlış, geri dön ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().. Parantez eklemeniz gerekir - df = df[(df.EPS > 2.0) & (df.EPS <4.0)]ancak bu sorunun cevabı değildir.
jezrael

-1

Nedense, daha önce gönderilen cevapların hiçbiri benim için işe yaramadı. Bu temel çözüm şunları yaptı:

df = df[df.EPS >= 0]

Tabii ki negatif sayılar içeren satırlar da düşecek. Eğer bunları istiyorsanız, muhtemelen bunu daha sonra eklemek akıllıdır.

df = df[df.EPS <= 0]

Bu tamamen farklı bir şey yapar, değil mi?
AMC

-1

Çözümlerden biri

df = df[df.isnull().sum(axis=1) <= Cutoff Value]

Başka bir yol olabilir

df= df.dropna(thresh=(df.shape[1] - Cutoff_value))

Umarım bunlar faydalıdır.

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.