পান্ডাস ডাটাফ্রেমের সারিগুলি কীভাবে ফেলে দেওয়া যায় যার একটি নির্দিষ্ট কলামের মান NaN


749

আমার কাছে এটি রয়েছে 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

আমি কেমন করে ঐটি করি?


21
ড্রপনা: পান্ডাস.পিডিটা.অর্গ / প্যান্ডাস-
ওয়াটার ওভারমায়ার

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

উত্তর:


652

ড্রপ করবেন না, কেবল সারিগুলিতে নিয়ে যান যেখানে ইপিএস NA নয়:

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

470
আমি এর pandas.notnullপরিবর্তেnp.isfinite
Wes McKinney

11
ছাড়ার চেয়ে অনুলিপি করা এবং অনুলিপি করার কোনও সুবিধা আছে কি?
রবার্ট মুয়েল

9
ত্রুটি তৈরি করে: TypeError: ufunc 'isfinite' ইনপুট ধরণের জন্য সমর্থিত নয়, এবং কাস্টিং বিধি '' নিরাপদ '' অনুযায়ী ইনপুটগুলি কোনও সমর্থিত প্রকারের সাথে নিরাপদে জোর করা যায়নি
ফিলিপ শোয়ার্জ

4
@ ওয়েস-ম্যাকিনে দয়া করে আমাকে জানান যে ড্রপানা () প্যান্ডাসের চেয়ে ভাল পছন্দ। এক্ষেত্রে কোনও উত্তর নেই? যদি তাই হয় তবে কেন?
স্ট্রফিল্ড

4
@ ফিলিপসওয়ার্জ এই ত্রুটিটি ঘটে যদি কলামে ( 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.rodna.html এ ডকস দেখুন ) রয়েছে।

বেশ সহজ!


281
আপনি ব্যবহার করতে পারেন df.dropna(subset = ['column_name'])। আশা করি কমপক্ষে একজনকে 'আমি কী ভুল করছি' এর অতিরিক্ত 5 সেকেন্ডের মধ্যে একজনকে বাঁচায়। দুর্দান্ত উত্তর, +1
জেমস টোবিন

10
@ জেমসটোবিন, আমি এর জন্য একটি ফাংশন লিখতে মাত্র 20 মিনিট ব্যয় করেছি! অফিসিয়াল ডকুমেন্টেশন খুব গুপ্ত ছিল: "অন্যান্য অক্ষের সাথে বিবেচনা করার জন্য লেবেলগুলি উদাহরণস্বরূপ, আপনি যদি সারিগুলি বাদ দিচ্ছেন তবে এগুলি অন্তর্ভুক্ত করার জন্য কলামগুলির একটি তালিকা হবে"। আমি বুঝতে অক্ষম ছিল, তারা কি বোঝানো ...
OSA

df.dropna(subset = ['column_name'])ঠিক আমি যা খুঁজছিলাম! ধন্যবাদ!
amalik2205

123

আমি জানি এটি ইতিমধ্যে উত্তর দেওয়া হয়েছে, তবে কেবলমাত্র আমান (যা দুর্দান্ত ছিল) এর সাধারণ বিবরণের বিপরীতে এই নির্দিষ্ট প্রশ্নের খাঁটি পান্ডাস সমাধানের জন্য এবং এরপরে অন্য কেউ ঘটলে:

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

10
আসলে, নির্দিষ্ট উত্তরটি হবে: df.dropna(subset=['EPS'])(আমানের সাধারণ বর্ণনার ভিত্তিতে, অবশ্যই এটি কাজ করেও)
জরিস

2
notnullওয়েস (পান্ডসের লেখক) অন্য একটি উত্তরে তাঁর মন্তব্যে যা বলেছিলেন তাও এটি।
কল্পনা 3

এটি সম্ভবত একটি অদ্ভুত প্রশ্ন। তবে আমি যখন ডিএফ [পিডি.নোটনল (...) বা ডিএফ.প্রপোনা করি তখন সূচকটি বাদ পড়ে। তাই আপনি যদি সেখানে দৈর্ঘ্য 200. একটি করে df মধ্যে সারি-সূচক 10 একটি নাল মান ছিল dataframe ড্রপ ফাংশন চলমান পরে 1 থেকে 9 এবং যেকোনোভাবে থেকে "পুনরায় সূচক" তাহলে 11 200. সূচক মান আছে
আকাশ গুপ্ত

আপনি নামটি না জানলে সংখ্যাযুক্ত কলামটি df[pd.notnull(df[df.columns[INDEX]])]কোথায় INDEXথাকতে পারে তা আপনি করতে পারেন
समुद्र 80000

60

আপনি এটি ব্যবহার করতে পারেন:

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

18
how='all', অপ্রয়োজনীয় এখানে কারণ আপনি উভয় তাই dataframe একটি ক্ষেত্র শুধুমাত্র সঙ্গে subsetting 'all'এবং 'any'একই প্রভাব ফেলবে না।
আন্তন প্রোটোপোভভ

35

সকল সমাধানগুলির মধ্যে সহজতম:

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

উপরের সমাধানটি এনপি.সিসিমাইট () ব্যবহারের চেয়ে আরও ভাল is


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.rodna.html


inplace=Trueএকটি উদ্ভট বিষয়, এবং এর কোনও প্রভাব নেই DataFrame.dropna()। দেখুন: github.com/pandas-dev/pandas/issues/16529
এএমসি

@ জো এর উত্তর থেকে এই উত্তরটি কীভাবে আলাদা? এছাড়াও, স্থানটি অবশেষে হ্রাস করা হবে, এটিকে ব্যবহার না করাই সেরা।
মিসানট্রুপ

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২ টি কলাম রয়েছে যার মধ্যে ১৯ টিতে কমপক্ষে একটি নাল মান রয়েছে।

আরও আপনি স্বয়ংক্রিয়ভাবে কলস এবং সারিগুলি সরিয়ে ফেলতে পারেন যার উপর নির্ভর করে আরও নাল মান রয়েছে
এখানে কোডটি যা বুদ্ধিমানভাবে এটি করে:

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
দুঃখিত, তবে ওপি অন্য কিছু চায়। বিটিডব্লিউ, আপনার কোডটি ভুল, ফিরে আসুন 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)]তবে এটি এই প্রশ্নের উত্তর নয়।
জিজরেল

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

আমি আশা করি এগুলি কার্যকর হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.