পান্ডাস থেকে জটিল মানদণ্ড নির্বাচন করা হচ্ছে। ডেটা ফ্রেম


234

উদাহরণস্বরূপ আমার কাছে সাধারণ ডিএফ রয়েছে:

import pandas as pd
from random import randint

df = pd.DataFrame({'A': [randint(1, 9) for x in xrange(10)],
                   'B': [randint(1, 9)*10 for x in xrange(10)],
                   'C': [randint(1, 9)*100 for x in xrange(10)]})

আমি কী 'এ' থেকে মানগুলি নির্বাচন করতে পারি যার জন্য 'বি' এর সাথে সম্পর্কিত মানগুলি 50 এর চেয়ে বেশি হবে এবং 'সি' - এর সমান নয় 900, পদ্ধতিগুলি এবং পান্ডসের প্রতিমা ব্যবহার করে?


df.queryএবং pd.evalএই ব্যবহারের ক্ষেত্রে ভাল মানায়। তথ্যের জন্য pd.eval()ফাংশন, তাদের বৈশিষ্ট্য ও ব্যবহারের ক্ষেত্রে পরিবার, অনুগ্রহ করে পরিদর্শন pd.eval ব্যবহার পান্ডাস মধ্যে ডায়নামিক এক্সপ্রেশন মূল্যায়ন ()
cs95

: যেমন ভাল @Gecko এর উত্তর চেক পারে stackoverflow.com/questions/13611065/...
নিকোলাস হামফ্রে

উত্তর:


390

নিশ্চিত! সেটআপ:

>>> import pandas as pd
>>> from random import randint
>>> df = pd.DataFrame({'A': [randint(1, 9) for x in range(10)],
                   'B': [randint(1, 9)*10 for x in range(10)],
                   'C': [randint(1, 9)*100 for x in range(10)]})
>>> df
   A   B    C
0  9  40  300
1  9  70  700
2  5  70  900
3  8  80  900
4  7  50  200
5  9  30  900
6  2  80  700
7  2  80  400
8  5  80  300
9  7  70  800

আমরা কলাম অপারেশনগুলি প্রয়োগ করতে পারি এবং বুলিয়ান সিরিজ অবজেক্টগুলি পেতে পারি:

>>> df["B"] > 50
0    False
1     True
2     True
3     True
4    False
5    False
6     True
7     True
8     True
9     True
Name: B
>>> (df["B"] > 50) & (df["C"] == 900)
0    False
1    False
2     True
3     True
4    False
5    False
6    False
7    False
8    False
9    False

[আপডেট করুন, নতুন স্টাইলে স্যুইচ করতে .loc]:

এবং তারপরে আমরা এগুলি অবজেক্টে সূচক করতে ব্যবহার করতে পারি। পাঠ্য অ্যাক্সেসের জন্য, আপনি সূচকগুলি চেইন করতে পারেন:

>>> df["A"][(df["B"] > 50) & (df["C"] == 900)]
2    5
3    8
Name: A, dtype: int64

তবে লেখার অ্যাক্সেসের জন্য এমন কোনও দর্শন এবং অনুলিপি করার মধ্যে পার্থক্যের কারণে আপনি নিজেকে সমস্যায় ফেলতে পারেন। .locপরিবর্তে আপনি ব্যবহার করতে পারেন :

>>> df.loc[(df["B"] > 50) & (df["C"] == 900), "A"]
2    5
3    8
Name: A, dtype: int64
>>> df.loc[(df["B"] > 50) & (df["C"] == 900), "A"].values
array([5, 8], dtype=int64)
>>> df.loc[(df["B"] > 50) & (df["C"] == 900), "A"] *= 1000
>>> df
      A   B    C
0     9  40  300
1     9  70  700
2  5000  70  900
3  8000  80  900
4     7  50  200
5     9  30  900
6     2  80  700
7     2  80  400
8     5  80  300
9     7  70  800

মনে রাখবেন যে আমি দুর্ঘটনাক্রমে টাইপ করেছি == 900এবং না != 900, বা ~(df["C"] == 900), তবে আমি এটি ঠিক করতে খুব অলস। পাঠকের জন্য অনুশীলন। : ^)


5
.locআপডেট সম্পর্কে - আমরা কোথায় একটি অনুলিপি পাই এবং কোথায় একটি দর্শন আছে তা যদি আপনি স্পষ্ট করেন তবে ভাল হবে।
গিল বেটস

3
কোনও পান্ডাস ডেটা ফ্রেম ফিল্টার করে ওআর অপারেটর ব্যবহার করা কি সম্ভব? উদাহরণস্বরূপ যদি কোনও কলাম মাস ছিল, আপনি ডিএফ = ডেটা ['মাস' == জান বা 'মাস' == ফিবি] বলতে পারবেন? এবং কোয়েরিকে আরও জটিল করে তুলতে একটি দ্বিতীয় কলাম অন্তর্ভুক্ত করুন, newdf যেখানে col_month = jan OR feb এবং col_day = সোমবার বা WendNESDAY
yoshiserry

7
@ যোশিসেরি: দয়া করে আলাদা প্রশ্ন হিসাবে এটি জিজ্ঞাসা করুন। কোনও পুরানো উত্তরের মন্তব্যে এটি এখানে কেউ দেখতে পাবেন না।
ডিএসএম

2
বন্ধনীগুলি ভুলবেন না - আপনি যেমন অদ্ভুত ত্রুটি পাবেন{TypeError}cannot compare a dtyped [int64] array with a scalar of type [bool]
Mr_and_Mrs_D

এই প্রথম বন্ধনী ব্যবহারের ফলে পুরো সিরিজ ধরে গণনা হয় না? যদি আমরা দক্ষতার জন্য বারবার সাবসেট করতে চাই?
ifly6

56

আর একটি সমাধান হল ক্যোয়ারী পদ্ধতিটি ব্যবহার করা :

import pandas as pd

from random import randint
df = pd.DataFrame({'A': [randint(1, 9) for x in xrange(10)],
                   'B': [randint(1, 9) * 10 for x in xrange(10)],
                   'C': [randint(1, 9) * 100 for x in xrange(10)]})
print df

   A   B    C
0  7  20  300
1  7  80  700
2  4  90  100
3  4  30  900
4  7  80  200
5  7  60  800
6  3  80  900
7  9  40  100
8  6  40  100
9  3  10  600

print df.query('B > 50 and C != 900')

   A   B    C
1  7  80  700
2  4  90  100
4  7  80  200
5  7  60  800

এখন আপনি যদি কলাম A এ ফিরে আসা মানগুলি পরিবর্তন করতে চান তবে আপনি তাদের সূচকটি সংরক্ষণ করতে পারেন:

my_query_index = df.query('B > 50 & C != 900').index

.... এবং .ilocএগুলি পরিবর্তন করতে ব্যবহার করুন:

df.iloc[my_query_index, 0] = 5000

print df

      A   B    C
0     7  20  300
1  5000  80  700
2  5000  90  100
3     4  30  900
4  5000  80  200
5  5000  60  800
6     3  80  900
7     9  40  100
8     6  40  100
9     3  10  600

12

এবং বন্ধনী ব্যবহার মনে রাখবেন!

মনে রাখবেন যে &অপারেটর যেমন >বা <ইত্যাদি অপারেটরদের উপর অগ্রাধিকার নেয়

4 < 5 & 6 > 4

মূল্যায়ন False। সুতরাং আপনি যদি ব্যবহার করছেন তবে pd.locআপনার লজিক্যাল স্টেটমেন্টের চারপাশে বন্ধনী রাখা দরকার, অন্যথায় আপনি একটি ত্রুটি পান। এজন্যই করুন:

df.loc[(df['A'] > 10) & (df['B'] < 15)]

পরিবর্তে

df.loc[df['A'] > 10 & df['B'] < 15]

যার ফলস্বরূপ হবে

প্রকারের ত্রুটি: কোনও ধরণের স্কেলারের সাথে কোনও ধরণের [ফ্লোট 64] অ্যারের তুলনা করতে পারে না


3

তুলনা করার জন্য ফাংশনে কিছুটা অন্তর্নির্মিত পান্ডাস ব্যবহার করতে পারেন। সুতরাং আপনি যদি "A" এর মানগুলি নির্বাচন করতে চান যা "B" এবং "C" এর শর্ত পূরণ করে (ধরে নিচ্ছেন যে আপনি কোনও ডেটা ফ্রেম পান্ডাস বস্তু ফিরে চান)

df[['A']][df.B.gt(50) & df.C.ne(900)]

df[['A']] আপনাকে ডেটাফ্রেমে ফর্ম্যাটটিতে কলামটি A ফেরত দেবে।

পান্ডাস 'জিটি' ফাংশনটি 50 টিরও বেশি বড় কলামের অবস্থানগুলিতে ফিরে আসবে এবং 'নে' 900 এর সমান নয়।

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