リストからNanを削除するにはどうすればよいですかPython / NumPy


96

カウント値のリストがあります。取得した値の1つは「nan」です。

countries= [nan, 'USA', 'UK', 'France']

削除しようとしましたが、毎回エラーが発生します

cleanedList = [x for x in countries if (math.isnan(x) == True)]
TypeError: a float is required

私がこれを試したとき:

cleanedList = cities[np.logical_not(np.isnan(countries))]
cleanedList = cities[~np.isnan(countries)]

TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

4
これは文字列のように見えますが"nan"、実際のNaN値ではありません。
BrenBarn 2014年

1
はい、それは文字列です。[x!= 'nan'の場合、国のxのx]
MarshalSHI 2014年

4
if condition == True不要ですので、いつでもできますif condition
2014年

これまでに提供された解決策は満足のいくものではありません。私は同じ問題を抱えています。基本的に、文字列では機能しません。したがって、あなたの場合np.isnan('USA')、同じエラーメッセージを送信します。解決策が見つかったらアップロードします。
Yohan Obadia 2017年

回答:


131

質問が変わったので、答えがあります:

math.isnanこれはfloat引数を想定しているため、を使用して文字列をテストすることはできません。あなたにはcountriesリスト、あなたは山車と文字列を持っています。

あなたの場合、以下で十分です:

cleanedList = [x for x in countries if str(x) != 'nan']

古い答え

あなたのcountriesリストでは、リテラル'nan'は次nanと同等のPythonfloatではなく文字列です。

float('NaN')

あなたの場合、以下で十分です:

cleanedList = [x for x in countries if x != 'nan']

1
論理的には、あなたの言うことは真実です。しかし、それは私にはうまくいきませんでした。
user3001937 2014年

次に、問題は別の領域にあります。指定した配列はmath.isnan、エラーを介して自然に発生する文字列です。

はい !出力を印刷すると、次のようになります:[nan、 'USA'、 'UK'、 'France']
user3001937 2014年

1
@ user3001937新しい情報に基づいて回答を更新しました

2
zhangxaochen:それは文字列ではなく、フロートです。更新された回答を注意深く見てください。Lego Stormtrooprxが文字列に変換しているので、比較することができます。と比較した場合でも、nanは常にfalseを返す==ためnan、これが最も簡単な比較方法です。
無料のMonica Cellio 2014年

17

問題は、np.isnan()文字列値を正しく処理しないという事実に起因します。たとえば、次の場合:

np.isnan("A")
TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

ただし、パンダバージョンpd.isnull()は数値と文字列値に対して機能します。

pd.isnull("A")
> False

pd.isnull(3)
> False

pd.isnull(np.nan)
> True

pd.isnull(None)
> True

15

あなたの例を使用して...

countries= [nan, 'USA', 'UK', 'France']

nanはnan(nan!= nan)およびcountries [0] = nanと等しくないため、次の点に注意する必要があります。

countries[0] == countries[0]
False

しかしながら、

countries[1] == countries[1]
True
countries[2] == countries[2]
True
countries[3] == countries[3]
True

したがって、以下が機能するはずです。

cleanedList = [x for x in countries if x == x]

1
これは文字列のリストにフロート(「ナン」)を持っている時に働く唯一の答えである
kmundnic

13
import numpy as np

mylist = [3, 4, 5, np.nan]
l = [x for x in mylist if ~np.isnan(x)]

これにより、すべてのNaNが削除されます。もちろん、ここでは文字列ではなく、実際のNaN(np.nan)だと思います。


1
これにより、エラーが発生します。TypeError:ufunc'isnan 'は入力タイプでサポートされておらず、キャストルール' 'safe' 'に従って、サポートされているタイプに入力を安全に強制変換できませんでした
Zak Keirn

1
なぜ単純ではないのx[~ np.isnan(x)]ですか?numpyではリスト内包表記は必要ありません。もちろん、xはnumpy配列だと思います。
BUE

質問が示唆するように、xはnumpy配列にはならないだろうと思いました。
AjayShah19年

フロートが期待されます。文字列@ZakKeirnとリスト上では動作しません
Shirish Bajpai

6

要素タイプを確認する場合

type(countries[1])

結果は<class float> 、次のコードを使用できるようになります。

[i for i in countries if type(i) is not float]



2

これを行う別の方法には、次のようなフィルターの使用が含まれます。

countries = list(filter(lambda x: str(x) != 'nan', countries))

1

あなたの例で'nan'は文字列なので、使用する代わりにisnan()文字列をチェックしてください

このような:

cleanedList = [x for x in countries if x != 'nan']

-1

たとえば、パンダは空白の値に対して「nan」を返すことに気づきました。文字列ではないため、一致させるには文字列に変換する必要があります。例えば:

ulist = df.column1.unique() #create a list from a column with Pandas which 
for loc in ulist:
    loc = str(loc)   #here 'nan' is converted to a string to compare with if
    if loc != 'nan':
        print(loc)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.