web-dev-qa-db-ja.com

特定の列の値がNaNであるPandas DataFrameの行を削除する方法

私はDataFrameを持っています:

>>> 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

EPSNaNではないレコード、つまりdf.drop(....)が以下のようにデータフレームを返すようにします。

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

それ、どうやったら出来るの?

554
bigbug

dropをしないでください。 EPS finite の行を取るだけです。

df = df[np.isfinite(df['EPS'])]
438
eumiro

この質問はすでに解決されていますが...

... 彼の元のコメント でWouterによって提案された解決策も考えてください。 dropna()を含む、欠損データを処理する機能は、明示的にパンダに組み込まれています。手動で行うよりもパフォーマンスが向上する可能性があるのとは別に、これらの機能には便利なさまざまなオプションがあります。

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

行の代わりに列を削除するなど、他のオプションもあります( http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html のドキュメントを参照)。

かなり便利!

726
Aman

私はこれがすでに答えられていることを知っていますが、Amanからの一般的な説明(これは素晴らしかった)とは対照的に、この問題に対する純粋なパンダ解決のためであり、

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

これを使うことができます:

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

最も簡単な解決策:

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

上記の解決策は、np.isfinite()を使用するよりもずっと優れています。

25
Gil Baggio

データフレームメソッド notnull または isnull 、または numpy.isnan の逆を使用できます。

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
21

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
10
MaxU

dropna を使えます

少なくとも1つの要素が欠けている行を削除します。

df=df.dropna()

欠損値を探す列を定義します。

df=df.dropna(subset=['column1', 'column1'])

他の例については this を参照してください。

注意:dropnaのaxisパラメータはバージョン0.23.0から非推奨です。

9
Umer

または(NaNをisnullでチェックし、次に~を使用して、NaNがない場合と反対にする):

df=df[~df['EPS'].isnull()]

今:

print(df)

です:

                 STK_ID  EPS  cash
STK_ID RPT_Date
600016 20111231  600016  4.3   NaN
601939 20111231  601939  2.5   NaN
7
U9-Forward

シンプルで簡単な方法

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

ソース: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html

2
Nursnaaz

「&」を使用して追加の条件を追加できることを意味します。

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

ステートメントを評価するときは、パンダは括弧を必要とします。

1
David

この答えは、上記のすべてよりはるかに簡単です。

df=df[df['EPS'].notnull()]
1
N T

どういうわけか以前に提出された答えのどれも私のために働きませんでした。この基本的な解決策は以下のとおりです。

df = df[df.EPS >= 0]

もちろん負の数の行も削除されます。それで、あなたがそれらを欲しがっているならば、それは後にこれを追加することもおそらく賢いです。

df = df[df.EPS <= 0]
0
samthebrand