পান্ডাস: ডেটা ফ্রেমকে ইনডেক্স করার সময় একাধিক শর্ত - অপ্রত্যাশিত আচরণ


134

আমি দুটি কলামে মান দ্বারা একটি ডেটাফ্রেমে সারিগুলি ফিল্টার করছি am

কোনও কারণে ওআর অপারেটর এমন আচরণ করে যেমন আমি আশা করি ও অপারেটর আচরণ করবে এবং বিপরীত হবে।

আমার পরীক্ষার কোড:

import pandas as pd

df = pd.DataFrame({'a': range(5), 'b': range(5) })

# let's insert some -1 values
df['a'][1] = -1
df['b'][1] = -1
df['a'][3] = -1
df['b'][4] = -1

df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a != -1) | (df.b != -1)]

print pd.concat([df, df1, df2], axis=1,
                keys = [ 'original df', 'using AND (&)', 'using OR (|)',])

এবং ফলাফল:

      original df      using AND (&)      using OR (|)    
             a  b              a   b             a   b
0            0  0              0   0             0   0
1           -1 -1            NaN NaN           NaN NaN
2            2  2              2   2             2   2
3           -1  3            NaN NaN            -1   3
4            4 -1            NaN NaN             4  -1

[5 rows x 6 columns]

আপনি দেখতে পাচ্ছেন, ANDঅপারেটর প্রতি সারিতে ড্রপ করে যার মধ্যে কমপক্ষে একটি মান সমান হয় -1। অন্যদিকে, ORঅপারেটরের উভয় মানগুলি -1সেগুলি ফেলে দেওয়ার জন্য সমান হওয়া দরকার । আমি ঠিক বিপরীত ফলাফল আশা করব। দয়া করে কেউ কি এই আচরণটি ব্যাখ্যা করতে পারে?

আমি পান্ডা ব্যবহার করছি 0.13.1।


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

উত্তর:


211

আপনি দেখতে পাচ্ছেন যে, ওআরডি অপারেটর প্রতিটি সারিতে ড্রপ করে যার মধ্যে কমপক্ষে একটি মান -1 সমান হয়। অন্যদিকে, ওআর অপারেটরের উভয় মানগুলি তাদের ড্রপ করার জন্য -1 এর সমান হওয়া দরকার।

সেটা ঠিক. মনে রাখবেন যে আপনি কী রাখতে চান তার শর্তে আপনি শর্তটি লিখছেন, আপনি কী নামাতে চান তার শর্তে নয়। এর জন্য df1:

df1 = df[(df.a != -1) & (df.b != -1)]

আপনি বলছেন "যে সারিগুলি df.a-1 নয় এবং -1 df.bনয়" রাখুন, যা কমপক্ষে একটি মান -1 হ'ল প্রতিটি সারি বাদ দেওয়ার সমান।

এর জন্য df2:

df2 = df[(df.a != -1) | (df.b != -1)]

আপনি "বলছে করছি সারি যা পারেন রাখা df.aবা df.bনয় -1", যা সারি যেখানে উভয় মান -1 ড্রপ সমান।

পিএস: শৃঙ্খলাবদ্ধ অ্যাক্সেস df['a'][1] = -1আপনাকে সমস্যায় ফেলতে পারে। এটি ব্যবহার করার অভ্যাসের দিকে পান ভালো .locএবং .iloc


24
DataFrame.query()এখানে খুব সুন্দর কাজ করে। df.query('a != -1 or b != -1')
ফিলিপ ক্লাউড

4
কেন জানতে পান্ডাস চায় ঘটতে &এবং |উপর andএবং or?
স্টোভ

2
@ স্টোভস: সাধারণ পাইথন কোডে andএবং orবেসিক পাইথন শব্দার্থবিজ্ঞান রয়েছে যা পরিবর্তন করা যায় না। &এবং |অন্যদিকে, সম্পর্কিত বিশেষ পদ্ধতি রয়েছে যা তাদের আচরণ নিয়ন্ত্রণ করে। (ক্যোয়ারী স্ট্রিংগুলিতে অবশ্যই আমরা আমাদের পছন্দসই কোন পার্সিং প্রয়োগ করতে পারি))
ডিএসএম

মজার বিষয় হল, এটি df[True & False]ব্যর্থ বলে মনে হয় তবে df[(True) & (False)]সফল হয় (এই উদাহরণে পরীক্ষিত হয় না)
পিট

একাধিক লাইন জুড়ে এই জাতীয় সিনট্যাক্সটি ভাঙ্গা সম্ভব হবে? সর্বাধিক পিইপি 8 কী হবে?
tommy.carstensen

41

আপনি ক্যোয়ারী () ব্যবহার করতে পারেন , অর্থাত:

df_filtered = df.query('a == 4 & b != 2')

আমার এমন একটি পরিস্থিতি রয়েছে যেখানে আমার মনে হয় এই বাক্য গঠনটি আরও বেশি অর্থবোধ করে যেমন: df.query ('' (a == 4 & b! = 2) | c == 3 ")
Aus_10

9

এখানে একটি সামান্য গাণিতিক যুক্তি তত্ত্ব :

"নট এন্ড নট বি" "নট (এআর বি)" এর মতোই , তাই:

"একটি নট -1 এবং বি এনইটি -1" "নট (এ -1 বা বি হয় -1)" এর সমতুল্য, যা "(এ -1 বা বি হয় -1) এর বিপরীতে (পরিপূরক )"

সুতরাং আপনি যদি সঠিক বিপরীত ফলাফল চান, df1 এবং df2 নীচের মত হওয়া উচিত:

df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a == -1) | (df.b == -1)]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.