पंडों DataFrame की पंक्तियों को कैसे ड्रॉप करें जिसका मान एक निश्चित कॉलम में NaN है


751

मेरे पास यह है DataFrameऔर केवल उन अभिलेखों को चाहते हैं जिनका EPSकॉलम नहीं है 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

... यानी कुछ df.drop(....)इस तरह के डेटाफ्रेम पाने के लिए:

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

मैं उसको कैसे करू?



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

जवाबों:


653

ड्रॉप न करें, बस उन पंक्तियों को लें जहाँ EPS NA नहीं है:

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

470
मैं pandas.notnullइसके बजाय का उपयोग करने की सलाह np.isfinite
दूंगा

11
क्या गिराने पर अनुक्रमण और नकल करने का कोई फायदा है?
रॉबर्ट मुइल जूल

9
त्रुटि बनाता है: TypeError: ufunc 'isfinite' इनपुट प्रकारों के लिए समर्थित नहीं है, और कास्टिंग नियम '' सुरक्षित '' के अनुसार इनपुट किसी भी समर्थित प्रकार के लिए सुरक्षित रूप से ज़ब्त नहीं किए जा सकते हैं
फिलिप श्वार्ज़

4
@ wes-mckinney कृपया मुझे बता सकती है कि क्या इस मामले में ड्रैंडा () पंडास.नोटनॉल से बेहतर विकल्प है? यदि ऐसा है, तो क्यों?
तूफानी

4
@PhilippSchwarz यह त्रुटि तब होती है जब स्तंभ ( EPSउदाहरण में) में तार या अन्य प्रकार होते हैं जिन्हें पचाया नहीं जा सकता है np.isfinite()। मैं pandas.notnull()इसे और अधिक उदारता से संभालने के लिए उपयोग करने की सलाह देता हूं ।
मानदंड

901

यह प्रश्न पहले से ही हल है, लेकिन ...

... राउटर द्वारा सुझाए गए समाधान पर भी अपनी मूल टिप्पणी पर विचार करें । सहित लापता डेटा को संभालने की क्षमता 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 पर डॉक्स देखें )।

बहुत आसान!


281
आप भी उपयोग कर सकते हैं df.dropna(subset = ['column_name'])। आशा है कि कम से कम एक व्यक्ति को 'क्या मैं गलत कर रहा हूँ' के अतिरिक्त 5 सेकंड बचाता है। शानदार जवाब, +1
जेम्स टोबिन

10
@JamesTobin, मैंने उसके लिए एक फ़ंक्शन लिखने के लिए सिर्फ 20 मिनट बिताए! आधिकारिक दस्तावेज बहुत गूढ़ था: "अन्य धुरी पर लेबल पर विचार करने के लिए, उदाहरण के लिए यदि आप पंक्तियों को छोड़ रहे हैं तो ये शामिल करने के लिए स्तंभों की एक सूची होगी"। मैं समझ नहीं पा रहा था, उनका क्या मतलब था ...
ओसा

df.dropna(subset = ['column_name'])वास्तव में मैं क्या देख रहा था! धन्यवाद!
amalik2205 21

123

मुझे पता है कि यह पहले ही उत्तर दिया जा चुका है, लेकिन केवल इस विशिष्ट प्रश्न के विशुद्ध रूप से पांडा समाधान के लिए अमन (जो अद्भुत था) से सामान्य विवरण के विपरीत है और इस मामले में कोई और होता है:

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

10
वास्तव में, विशिष्ट उत्तर होगा: df.dropna(subset=['EPS'])(अमन के सामान्य विवरण के आधार पर, यह भी काम करता है)
जॉरिस

2
notnullयह भी है कि वेस (पंडों के लेखक) ने एक अन्य उत्तर पर अपनी टिप्पणी में क्या सुझाव दिया।
काल्पनिक जूल

यह शायद एक सवाल है। लेकिन जब मैं df [pd.notnull (...) या df.dropna करता हूं तो इंडेक्स गिर जाता है। यदि लंबाई 200 की df में पंक्ति-सूचकांक 10 में एक शून्य मान था, तो ड्रॉप फ़ंक्शन को चलाने के बाद डेटाफ्रेम में 1 से 9 और फिर 11 से 200 तक सूचकांक मान हैं। वैसे भी इसे "
आकाश

यदि आप नाम नहीं जानते हैं, तो आप भी df[pd.notnull(df[df.columns[INDEX]])]कहां कर सकते हैंINDEX
20800 पर Ocean800

60

आप इसका उपयोग कर सकते हैं:

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

18
how='all'यहाँ निरर्थक है, क्योंकि आप डेटाफ़्रेम को केवल एक फ़ील्ड के साथ उप-विभाजित कर रहे हैं, इसलिए दोनों 'all'का 'any'प्रभाव समान होगा।
एंटोन प्रोतोपोपोव

35

सभी समाधानों में सबसे सरल:

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

उपरोक्त समाधान np.isfinite () का उपयोग करने से बेहतर है


22

आप dataframe विधि इस्तेमाल कर सकते हैं 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

18

सरल और आसान तरीका

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

स्रोत: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html


inplace=Trueएक विचित्र विषय है, और इसका कोई प्रभाव नहीं है DataFrame.dropna()। देखें: github.com/pandas-dev/pandas/issues/16529
AMC

यह उत्तर @ जो के उत्तर से कैसे भिन्न है? इसके अलावा, अंत में पदावनत किया जाएगा, सबसे अच्छा है कि इसका उपयोग न करें।
मिसट्रोप

10

अभी तक एक और समाधान जो इस तथ्य का उपयोग करता है कि 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

बड़ी संख्या में कॉलम रखने वाले डेटासेट में यह देखने के लिए बेहतर है कि कितने कॉलम में शून्य मान हैं और कितने नहीं हैं।

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

मेरे डेटाफ्रेम में उदाहरण के लिए इसमें 82 कॉलम थे, जिनमें से 19 में कम से कम एक शून्य मान था।

इसके अलावा, आप स्वतः ही उन कॉल और पंक्तियों को हटा सकते हैं जिनके आधार पर अधिक शून्य मान हैं।
यह वह कोड है जो यह समझदारी से करता है:

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

नोट: उपरोक्त कोड आपके सभी अशक्त मूल्यों को हटा देता है। यदि आप शून्य मान चाहते हैं, तो उन्हें पहले संसाधित करें।


एक और प्रश्न लिंक है
प्रदीप सिंह

0

यह जोड़ा जा सकता है कि 'और' का उपयोग अतिरिक्त स्थितियों को जोड़ने के लिए किया जा सकता है

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

ध्यान दें कि बयानों का मूल्यांकन करते समय, पांडा को कोष्ठक की आवश्यकता होती है।


2
क्षमा करें, लेकिन ओपी कुछ और चाहते हैं। Btw, आपका कोड गलत है, वापस लौटें ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().। आपको कोष्ठक जोड़ने की आवश्यकता है - df = df[(df.EPS > 2.0) & (df.EPS <4.0)]लेकिन यह भी इस प्रश्न का उत्तर नहीं है।
jezrael

-1

किसी कारण के लिए पहले से प्रस्तुत जवाबों में से कोई भी मेरे लिए काम नहीं करता है। इस बुनियादी समाधान ने किया:

df = df[df.EPS >= 0]

हालांकि निश्चित रूप से कि नकारात्मक संख्या के साथ पंक्तियों को छोड़ देंगे, भी। तो अगर आप चाहते हैं कि यह शायद यह जोड़ने के लिए स्मार्ट है, के बाद भी।

df = df[df.EPS <= 0]

यह कुछ पूरी तरह से अलग करता है, नहीं?
एएमसी

-1

इसका एक समाधान हो सकता है

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

दूसरा तरीका हो सकता है

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

मुझे उम्मीद है कि ये उपयोगी हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.