ValueError: อินพุตมี NaN, อินฟินิตี้หรือค่าใหญ่เกินไปสำหรับ dtype ('float32')


41

ฉันได้รับ ValueError เมื่อทำนายข้อมูลการทดสอบโดยใช้โมเดล RandomForest

รหัสของฉัน:

clf = RandomForestClassifier(n_estimators=10, max_depth=6, n_jobs=1, verbose=2)
clf.fit(X_fit, y_fit)

df_test.fillna(df_test.mean())
X_test = df_test.values  
y_pred = clf.predict(X_test)

ข้อผิดพลาด:

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

ฉันจะค้นหาค่าที่ไม่ดีในชุดข้อมูลการทดสอบได้อย่างไร นอกจากนี้ฉันไม่ต้องการลบบันทึกเหล่านี้ฉันสามารถแทนที่พวกเขาด้วยค่าเฉลี่ยหรือค่ามัธยฐาน?

ขอบคุณ

คำตอบ:


44

เมื่อnp.isnan(X)คุณได้รับหน้ากากบูลีนกลับมาพร้อมกับ True สำหรับตำแหน่งที่มีNaNs

เมื่อnp.where(np.isnan(X))คุณคืนค่า tuple ด้วย i, j พิกัดของNaNs

ในที่สุดกับnp.nan_to_num(X)คุณ "แทนที่น่านด้วยศูนย์และ inf ด้วยตัวเลข จำกัด "

หรือคุณสามารถใช้:

  • sklearn.impute.SimpleImputerสำหรับการใส่ค่าเฉลี่ย / ค่ามัธยฐานของค่าที่หายไปหรือ
  • นุ่น ' pd.DataFrame(X).fillna()ถ้าคุณต้องการอย่างอื่นนอกจากเติมด้วยเลขศูนย์

ฉันชอบเงื่อนไขการระบุตัวตนสำหรับการตรวจสอบน่านถ้า x! = x return ไม่มีหลายครั้ง np.isnan (x) ล้มเหลวสำหรับฉันอย่าจำเหตุผล
Itachi

1
ไม่แนะนำให้แทนที่ค่า NaN ด้วยค่าศูนย์ ค่า NaN อาจยังคงมีความสำคัญในการขาดหายไปและการใส่เข้าไปด้วยค่าศูนย์อาจเป็นสิ่งที่แย่ที่สุดที่คุณสามารถทำได้และวิธีการใส่ร้ายที่เลวร้ายที่สุดที่คุณใช้ ไม่เพียง แต่คุณจะแนะนำศูนย์โดยพลการซึ่งอาจทำให้ตัวแปรของคุณเอียง แต่ 0 อาจไม่ได้เป็นค่าที่ยอมรับได้ในตัวแปรของคุณซึ่งหมายความว่าตัวแปรของคุณอาจไม่มีศูนย์จริง
hussam

ฉันรู้ว่าฉันไม่ได้ให้คำแนะนำใด ๆ หากคุณต้องการใส่ข้อมูลของคุณให้ใช้ค่าเฉลี่ยการหมุน.rolling()เพื่อแทนที่ค่าที่หายไปด้วยค่าเฉลี่ยของหน้าต่างกลิ้ง หากคุณต้องการบางสิ่งบางอย่างใช้โมดูลที่แข็งแกร่งยิ่งขึ้น <b> หายไป </b> คุณสามารถใช้MissForestสำหรับการสุ่มตัวอย่างตาม
hussam

7

สมมติว่าX_testเป็น dataframe ของ pandas คุณสามารถใช้DataFrame.fillnaเพื่อแทนที่ค่า NaN ด้วยค่าเฉลี่ย:

X_test.fillna(X_test.mean())

X_test เป็นอาร์เรย์ที่ไม่มีค่า เพิ่งอัปเดต df_test ในคำถามเดิมยังคงมีข้อผิดพลาดเดียวกัน ...
Edamame

6

สำหรับใครก็ตามที่เกิดเหตุการณ์เช่นนี้เพื่อแก้ไขต้นฉบับ:

X_test.fillna(X_train.mean(), inplace=True)

วิธีเขียนทับต้นฉบับ:

X_test = X_test.fillna(X_train.mean())

วิธีตรวจสอบว่าคุณอยู่ในมุมมองสำเนาหรือไม่:

X_test._is_view

2
ในขณะที่นี่เป็นเรื่องจริงทางเทคนิคมันผิดจริง คุณไม่สามารถเติม X_test NAs ด้วยค่าเฉลี่ย X_test ได้เพราะในชีวิตจริงคุณจะไม่มีค่าเฉลี่ย X_test เมื่อคุณคาดการณ์ตัวอย่าง คุณควรใช้ค่าเฉลี่ย X_train เพราะนี่เป็นข้อมูลเดียวที่คุณมีอยู่ในมือ (ในสถานการณ์ 99%)
Omri374

4

อย่าลืม

col_mask=df.isnull().any(axis=0) 

ซึ่งส่งกลับมาสก์บูลีนที่ระบุค่า np.nan

row_mask=df.isnull().any(axis=1)

ซึ่งส่งคืนแถวที่ np.nan ปรากฏขึ้น จากนั้นด้วยการจัดทำดัชนีอย่างง่ายคุณสามารถตั้งค่าสถานะคะแนนทั้งหมดของคุณนั่นคือ np.nan

df.loc[row_mask,col_mask]

2

ฉันประสบปัญหาที่คล้ายกันและเห็นว่าคนจัดการจับ NaN และ Inf ต่างกัน
ในกรณีที่ข้อมูลของคุณมี Inf ให้ลองทำดังนี้

np.where(x.values >= np.finfo(np.float64).max)
Where x is my pandas Dataframe 

สิ่งนี้จะให้ตำแหน่งของสถานที่ที่มีค่า NA อยู่

ในกรณีที่ข้อมูลของคุณมีน่านลองสิ่งนี้:

np.isnan(x.values.any())

2

อย่าลืมตรวจสอบค่า inf เช่นกัน สิ่งเดียวที่ใช้ได้สำหรับฉัน:

df[df==np.inf]=np.nan
df.fillna(df.mean(), inplace=True)

และดียิ่งขึ้นถ้าคุณใช้ sklearn

def replace_missing_value(df, number_features):

    imputer = Imputer(strategy="median")
    df_num = df[number_features]
    imputer.fit(df_num)
    X = imputer.transform(df_num)
    res_def = pd.DataFrame(X, columns=df_num.columns)
    return res_def

เมื่อ number_features จะเป็นอาร์เรย์ของป้ายกำกับ number_features ตัวอย่างเช่น:

number_features = ['median_income', 'gdp']

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.