ข้อผิดพลาดของ sklearn ValueError: อินพุตมี NaN อินฟินิตี้หรือค่าใหญ่เกินไปสำหรับ dtype ('float64')


129

ฉันใช้ sklearn และมีปัญหากับการเผยแพร่ความสัมพันธ์ ฉันได้สร้างเมทริกซ์อินพุตและได้รับข้อผิดพลาดต่อไปนี้

ValueError: Input contains NaN, infinity or a value too large for dtype('float64').

ฉันได้วิ่ง

np.isnan(mat.any()) #and gets False
np.isfinite(mat.all()) #and gets True

ฉันลองใช้

mat[np.isfinite(mat) == True] = 0

เพื่อลบค่าอนันต์ แต่ก็ไม่ได้ผลเช่นกัน ฉันจะทำอย่างไรเพื่อกำจัดค่าอนันต์ในเมทริกซ์ของฉันเพื่อให้ฉันสามารถใช้อัลกอริทึมการแพร่กระจายความสัมพันธ์ได้

ฉันใช้งูใหญ่และงูหลาม 2.7.9


3
ฉันลงคะแนนเพื่อปิดสิ่งนี้เนื่องจากผู้เขียนบอกว่าตัวเองข้อมูลของเขาไม่ถูกต้องและแม้ว่าทุกอย่างจะชี้ไปที่มัน แต่เขาก็ไม่ได้ตรวจสอบความถูกต้อง - ข้อมูลเทียบเท่ากับการพิมพ์ผิดซึ่งเป็นเหตุผลในการปิด
Marcus Müller

11
ฉันมีปัญหาเดียวกันกับชุดข้อมูลของฉัน ท้ายที่สุด: ความผิดพลาดของข้อมูลไม่ใช่ข้อผิดพลาดในการเรียนรู้ของ scikit คำตอบด้านล่างส่วนใหญ่มีประโยชน์ แต่ทำให้เข้าใจผิด ตรวจสอบตรวจสอบตรวจสอบข้อมูลของคุณให้แน่ใจว่าเมื่อแปลงfloat64เป็นทั้ง จำกัด nanและไม่ได้ ข้อความแสดงข้อผิดพลาดนั้นเหมาะสม - นี่เป็นปัญหาสำหรับทุกคนที่พบว่าตัวเองอยู่ที่นี่
Owen

1
สำหรับเร็กคอร์ดและ +1 สำหรับ @Owen ให้ตรวจสอบข้อมูลอินพุตของคุณและตรวจสอบให้แน่ใจว่าคุณไม่มีค่าที่ขาดหายไปในแถวหรือตารางใด ๆ คุณสามารถใช้คลาส Imputer เพื่อหลีกเลี่ยงปัญหานี้
abautista

คำตอบ:


103

สิ่งนี้อาจเกิดขึ้นใน scikit และขึ้นอยู่กับว่าคุณกำลังทำอะไรอยู่ ขอแนะนำให้อ่านเอกสารสำหรับฟังก์ชันที่คุณใช้ คุณอาจกำลังใช้อันที่ขึ้นอยู่กับเช่นว่าเมทริกซ์ของคุณเป็นบวกแน่นอนและไม่เป็นไปตามเกณฑ์นั้น

แก้ไข : ฉันจะพลาดได้อย่างไร:

np.isnan(mat.any()) #and gets False
np.isfinite(mat.all()) #and gets True

เห็นได้ชัดว่าผิด ขวาจะเป็น:

np.any(np.isnan(mat))

และ

np.all(np.isfinite(mat))

คุณต้องการตรวจสอบว่าองค์ประกอบใด ๆ คือ NaN และไม่ว่าค่าที่ส่งคืนของanyฟังก์ชันเป็นตัวเลข ...


4
เอกสารไม่ได้กล่าวถึงอะไรเกี่ยวกับข้อผิดพลาดนี้ฉันต้องการวิธีกำจัดค่าที่ไม่มีที่สิ้นสุดออกจากอาร์เรย์ nupy ของฉัน
Ethan Waldie

3
อย่างที่ฉันพูด: อาจไม่อยู่ในอาร์เรย์อินพุตของคุณ อาจเกิดขึ้นในคณิตศาสตร์ที่เกิดขึ้นระหว่างอินพุตและเอาต์พุตที่มีมนต์ขลัง ประเด็นคือคณิตศาสตร์ทั้งหมดนี้ขึ้นอยู่กับเงื่อนไขบางประการสำหรับการป้อนข้อมูล คุณต้องอ่านเอกสารอย่างละเอียดเพื่อดูว่าข้อมูลที่คุณป้อนนั้นสอดคล้องกับเงื่อนไขเหล่านี้หรือไม่
Marcus Müller

1
@ MarcusMüllerคุณช่วยชี้ตำแหน่งของเอกสารนี้ที่พวกเขาระบุข้อกำหนดของเมทริกซ์อินพุตได้ไหม ดูเหมือนว่าฉันไม่พบ "เอกสาร" ที่คุณอ้างถึง ขอบคุณ :)
user2253546

39

ฉันได้รับข้อความข้อผิดพลาดเดียวกันเมื่อใช้sklearnกับหมีแพนด้า วิธีแก้ปัญหาของฉันคือการรีเซ็ตดัชนีของดาต้าเฟรมของฉันdfก่อนที่จะเรียกใช้รหัส sklearn:

df = df.reset_index()

ฉันพบปัญหานี้หลายครั้งเมื่อฉันลบบางรายการในของฉันdfเช่น

df = df[df.label=='desired_one']

1
ผมรักคุณ! นั่นเป็นตัวอย่างที่หายากสำหรับฉันในการหาวิธีแก้ปัญหาที่ถูกต้องทั้งๆที่ไม่รู้ว่าอะไรเป็นสาเหตุของข้อผิดพลาด
Alexandr Kapshuk

การทำ df.reset_index () จะเป็นการเพิ่ม "ดัชนี" เป็นคอลัมน์ใน df ที่เป็นผลลัพธ์ ซึ่งอาจไม่เป็นประโยชน์สำหรับทุกสถานการณ์ หาก df.reset_index (drop = True) ทำงานมันจะทำให้เกิดข้อผิดพลาดเดียวกัน
smm

16

นี่คือหน้าที่ของฉัน (บนพื้นฐานนี้ ) ในการทำความสะอาดชุดของnan, Infและเซลล์ที่ขาดหายไป (สำหรับชุดข้อมูลเบ้):

import pandas as pd

def clean_dataset(df):
    assert isinstance(df, pd.DataFrame), "df needs to be a pd.DataFrame"
    df.dropna(inplace=True)
    indices_to_keep = ~df.isin([np.nan, np.inf, -np.inf]).any(1)
    return df[indices_to_keep].astype(np.float64)

ทำไมน้องแนนทิ้งสองครั้ง ครั้งแรกกับdropnaครั้งที่สองเมื่อวาง inf
luca

ฉันสูญเสียข้อมูลบางส่วนเมื่อฉันใช้ฟังก์ชันนี้เพื่อล้างชุดข้อมูลของฉัน ทำไม?
hackerbuddy

2
นี่เป็นคำตอบเดียวที่ได้ผล ฉันลอง 20 คำตอบอื่น ๆ เกี่ยวกับ SO ที่ไม่ได้ผล ฉันคิดว่าคนนี้ต้องการการโหวตเพิ่มขึ้น
Contango


10

นี่คือการตรวจสอบที่ล้มเหลว:

ซึ่งกล่าวว่า

def _assert_all_finite(X):
    """Like assert_all_finite, but only for ndarray."""
    X = np.asanyarray(X)
    # First try an O(n) time, O(1) space solution for the common case that
    # everything is finite; fall back to O(n) space np.isfinite to prevent
    # false positives from overflow in sum method.
    if (X.dtype.char in np.typecodes['AllFloat'] and not np.isfinite(X.sum())
            and not np.isfinite(X).all()):
        raise ValueError("Input contains NaN, infinity"
                         " or a value too large for %r." % X.dtype)

ดังนั้นตรวจสอบให้แน่ใจว่าคุณมีค่าที่ไม่ใช่ NaN ในอินพุตของคุณ และค่าทั้งหมดนั้นเป็นค่าลอย ไม่ควรมีค่าใดเป็น Inf อย่างใดอย่างหนึ่ง


5

ด้วย python 3 เวอร์ชันนี้:

/opt/anaconda3/bin/python --version
Python 3.6.0 :: Anaconda 4.3.0 (64-bit)

เมื่อดูรายละเอียดของข้อผิดพลาดฉันพบบรรทัดของรหัสที่ทำให้เกิดความล้มเหลว:

/opt/anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py in _assert_all_finite(X)
     56             and not np.isfinite(X).all()):
     57         raise ValueError("Input contains NaN, infinity"
---> 58                          " or a value too large for %r." % X.dtype)
     59 
     60 

ValueError: Input contains NaN, infinity or a value too large for dtype('float64').

จากสิ่งนี้ฉันสามารถแยกวิธีที่ถูกต้องในการทดสอบสิ่งที่เกิดขึ้นกับข้อมูลของฉันโดยใช้การทดสอบเดียวกันซึ่งล้มเหลวโดยข้อความแสดงข้อผิดพลาด: np.isfinite(X)

จากนั้นด้วยการวนซ้ำที่รวดเร็วและสกปรกฉันพบว่าข้อมูลของฉันประกอบด้วยnans:

print(p[:,0].shape)
index = 0
for i in p[:,0]:
    if not np.isfinite(i):
        print(index, i)
    index +=1

(367340,)
4454 nan
6940 nan
10868 nan
12753 nan
14855 nan
15678 nan
24954 nan
30251 nan
31108 nan
51455 nan
59055 nan
...

ตอนนี้สิ่งที่ฉันต้องทำคือลบค่าที่ดัชนีเหล่านี้


4

ฉันพบข้อผิดพลาดหลังจากพยายามเลือกชุดย่อยของแถว:

df = df.reindex(index=my_index)

ปรากฎว่าmy_indexค่าอยู่ที่ไม่ได้มีอยู่ในdf.indexเพื่อฟังก์ชั่น Reindex nanแทรกแถวใหม่บางและเต็มไปพวกเขาด้วย


2

ในกรณีส่วนใหญ่การกำจัดค่าอนันต์และค่าว่างจะช่วยแก้ปัญหานี้ได้

กำจัดค่าที่ไม่มีที่สิ้นสุด

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

กำจัดค่า null ในแบบที่คุณต้องการค่าเฉพาะเช่น 999 ค่าเฉลี่ยหรือสร้างฟังก์ชันของคุณเองเพื่อกำหนดค่าที่ขาดหายไป

df.fillna(999, inplace=True)

2

ฉันมีข้อผิดพลาดเดียวกันและในกรณีของฉัน X และ y เป็นดาต้าเฟรมดังนั้นฉันต้องแปลงเป็นเมทริกซ์ก่อน:

X = X.values.astype(np.float)
y = y.values.astype(np.float)

แก้ไข: X.as_matrix () ที่แนะนำเดิมเลิกใช้แล้ว


1

ฉันได้รับข้อผิดพลาดเดียวกัน มันใช้งานได้df.fillna(-99999, inplace=True)ก่อนทำการเปลี่ยนทดแทน ฯลฯ


4
นี่คือการแก้ไขสกปรก มีเหตุผลว่าทำไมอาร์เรย์ของคุณจึงมีnanค่า คุณควรจะพบมัน
Elias Strehle

ข้อมูลอาจมี nan และทำให้มีวิธีแทนที่ด้วยข้อมูลด้วยค่าที่เขา / เธอพบว่ายอมรับได้
user2867432

0

ในกรณีของฉันปัญหาคือฟังก์ชัน scikit จำนวนมากส่งคืนอาร์เรย์ numpy ซึ่งไม่มีดัชนีแพนด้า ดังนั้นจึงมีดัชนีไม่ตรงกันเมื่อฉันใช้อาร์เรย์จำนวนนับเหล่านั้นเพื่อสร้าง DataFrames ใหม่จากนั้นฉันจึงพยายามผสมเข้ากับข้อมูลเดิม


0

ลบค่าอนันต์ทั้งหมด:

(และแทนที่ด้วย min หรือ max สำหรับคอลัมน์นั้น)

# find min and max values for each column, ignoring nan, -inf, and inf
mins = [np.nanmin(matrix[:, i][matrix[:, i] != -np.inf]) for i in range(matrix.shape[1])]
maxs = [np.nanmax(matrix[:, i][matrix[:, i] != np.inf]) for i in range(matrix.shape[1])]

# go through matrix one column at a time and replace  + and -infinity 
# with the max or min for that column
for i in range(log_train_arr.shape[1]):
    matrix[:, i][matrix[:, i] == -np.inf] = mins[i]
    matrix[:, i][matrix[:, i] == np.inf] = maxs[i]

-1

ลอง

mat.sum()

หากผลรวมของข้อมูลของคุณเป็นอินฟินิตี้ (มากกว่าค่าลอยสูงสุดซึ่งเป็น 3.402823e + 38) คุณจะได้รับข้อผิดพลาดนั้น

ดูฟังก์ชัน _assert_all_finite ใน validation.py จากซอร์สโค้ด scikit:

if is_float and np.isfinite(X.sum()):
    pass
elif is_float:
    msg_err = "Input contains {} or a value too large for {!r}."
    if (allow_nan and np.isinf(X).any() or
            not allow_nan and not np.isfinite(X).all()):
        type_err = 'infinity' if allow_nan else 'NaN, infinity'
        # print(X.sum())
        raise ValueError(msg_err.format(type_err, X.dtype))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.