পান্ডাস মাল্টিআইডেক্স ডেটা ফ্রেমে সারি নির্বাচন করুন


145

যার সূচকটি মাল্টিআইডেক্স হয় তার কোনও ডাটাফ্রেমের সারি / ফিল্টার সর্বাধিক সাধারণ পান্ডা উপায়গুলি কী কী ?

  • একক মান / লেবেলের উপর ভিত্তি করে স্লাইসিং
  • এক বা একাধিক স্তর থেকে একাধিক লেবেলের উপর ভিত্তি করে স্লাইসিং
  • বুলিয়ান শর্ত এবং অভিব্যক্তিগুলিতে ফিল্টারিং
  • কোন পরিস্থিতিতে কোন পরিস্থিতিতে প্রযোজ্য

সরলতার জন্য অনুমান:

  1. ইনপুট ডেটাফ্রেমের সদৃশ সূচি কী নেই have
  2. নীচে ইনপুট ডেটাফ্রেমের মাত্র দুটি স্তর রয়েছে। (এখানে প্রদর্শিত বেশিরভাগ সমাধান এন স্তরে সাধারণীকরণ করা হয়েছে)

উদাহরণ ইনপুট:

mux = pd.MultiIndex.from_arrays([
    list('aaaabbbbbccddddd'),
    list('tuvwtuvwtuvwtuvw')
], names=['one', 'two'])

df = pd.DataFrame({'col': np.arange(len(mux))}, mux)

         col
one two     
a   t      0
    u      1
    v      2
    w      3
b   t      4
    u      5
    v      6
    w      7
    t      8
c   u      9
    v     10
d   w     11
    t     12
    u     13
    v     14
    w     15

প্রশ্ন 1: একটি একক আইটেম নির্বাচন করা

"একটি" স্তর "এক" থাকা সারিগুলি কীভাবে নির্বাচন করব?

         col
one two     
a   t      0
    u      1
    v      2
    w      3

অতিরিক্তভাবে, আমি কীভাবে আউটপুটে "এক" স্তরটি ফেলে দিতে সক্ষম হব?

     col
two     
t      0
u      1
v      2
w      3

প্রশ্ন 1 বি
"টি" স্তরের "t" মানের সাথে সমস্ত সারিটি আমি কীভাবে স্লাইস করব?

         col
one two     
a   t      0
b   t      4
    t      8
d   t     12

প্রশ্ন 2: একটি স্তরে একাধিক মান নির্বাচন করা

"এক" স্তরের আইটেম "বি" এবং "ডি" এর সাথে সম্পর্কিত সারিগুলি আমি কীভাবে নির্বাচন করতে পারি?

         col
one two     
b   t      4
    u      5
    v      6
    w      7
    t      8
d   w     11
    t     12
    u     13
    v     14
    w     15

প্রশ্ন 2 বি
"টি" এবং "ডাব্লু" স্তরের "দুই" স্তরের সাথে সম্পর্কিত সমস্ত মান আমি কীভাবে পাব?

         col
one two     
a   t      0
    w      3
b   t      4
    w      7
    t      8
d   w     11
    t     12
    w     15

প্রশ্ন 3: একটি একক ক্রস বিভাগ কাটা (x, y)

আমি ক্রস বিভাগটি কীভাবে পুনরুদ্ধার করব, অর্থাত্, একটি একক সারি যা থেকে সূচকের জন্য নির্দিষ্ট মান রয়েছে df? বিশেষত, আমি ('c', 'u')প্রদত্ত ক্রস বিভাগটি কীভাবে পুনরুদ্ধার করব

         col
one two     
c   u      9

প্রশ্ন 4: একাধিক ক্রস বিভাগ কাটা [(a, b), (c, d), ...]

আমি দুটি সারি কীভাবে নির্বাচন করব ('c', 'u')এবং ('a', 'w')?

         col
one two     
c   u      9
a   w      3

প্রশ্ন 5: স্তর প্রতি এক আইটেম কাটা

"স্তরের" এক "বা" টি "স্তরের" টি "এর সাথে সম্পর্কিত সমস্ত সারি কীভাবে পুনরুদ্ধার করব?

         col
one two     
a   t      0
    u      1
    v      2
    w      3
b   t      4
    t      8
d   t     12

প্রশ্ন 6: নির্বিচারে স্লাইসিং

আমি কীভাবে নির্দিষ্ট ক্রস বিভাগগুলি স্লাইস করতে পারি? "ক" এবং "বি" এর জন্য আমি উপ-স্তরের "ইউ" এবং "ভি" সহ সমস্ত সারি নির্বাচন করতে চাই এবং "ডি" এর জন্য আমি উপ-স্তরের "ডাব্লু" দিয়ে সারি নির্বাচন করতে চাই।

         col
one two     
a   u      1
    v      2
b   u      5
    v      6
d   w     11
    w     15

প্রশ্ন 7 নম্বরের স্তরের সমন্বিত একটি অনন্য সেটআপ ব্যবহার করবে:

np.random.seed(0)
mux2 = pd.MultiIndex.from_arrays([
    list('aaaabbbbbccddddd'),
    np.random.choice(10, size=16)
], names=['one', 'two'])

df2 = pd.DataFrame({'col': np.arange(len(mux2))}, mux2)

         col
one two     
a   5      0
    0      1
    3      2
    3      3
b   7      4
    9      5
    3      6
    5      7
    2      8
c   4      9
    7     10
d   6     11
    8     12
    8     13
    1     14
    6     15

প্রশ্ন 7: মাল্টিইন্ডেক্সের পৃথক স্তরে সংখ্যাগত বৈষম্য দ্বারা ফিল্টারিং

"দুই" স্তরের মান 5 এর চেয়ে বেশি যেখানে আমি কীভাবে সমস্ত সারি পাব?

         col
one two     
b   7      4
    9      5
c   7     10
d   6     11
    8     12
    8     13
    6     15

নোট: এই পোস্টটি হবে না MultiIndexes, কিভাবে কোন কর্মক্ষমতা সংক্রান্ত আলোচনা (এই অন্য সময় জন্য পৃথক বিষয় নেই) তাদের উপর নিয়োগ কাজগুলি করতে, অথবা তৈরি করার পদ্ধতি মধ্য দিয়ে যেতে।

উত্তর:


166

মাল্টিআইডেক্স / অ্যাডভান্সড ইনডেক্সিং

দ্রষ্টব্য
এই পোস্টটি নিম্নলিখিত পদ্ধতিতে গঠন করা হবে:

  1. ওপিতে যে প্রশ্নগুলি করা হয়েছে সেগুলি একে একে সম্বোধন করা হবে
  2. প্রতিটি প্রশ্নের জন্য, এই সমস্যাটি সমাধান করতে এবং প্রত্যাশিত ফলাফল পাওয়ার ক্ষেত্রে এক বা একাধিক পদ্ধতি প্রযোজ্য হবে।

বিঃদ্রঃ গুলি (এর মতো এটির মতো) অতিরিক্ত কার্যকারিতা, বাস্তবায়নের বিশদ এবং হস্তের বিষয়টিতে অন্যান্য তথ্যের কার্সারি সম্পর্কে শিখতে আগ্রহী পাঠকদের জন্য অন্তর্ভুক্ত করা হবে। এই নোটগুলি দস্তাবেজগুলিকে ঝাঁকিয়ে দেওয়া এবং বিভিন্ন অস্পষ্ট বৈশিষ্ট্য উদ্ঘাটিত করার মাধ্যমে এবং আমার নিজের (স্বীকৃতভাবে সীমাবদ্ধ) অভিজ্ঞতা থেকে সংকলিত হয়েছে।

সমস্ত কোড নমুনা তৈরি এবং পরীক্ষিত হয়েছে পান্ডাস v0.23.4, পাইথন3.7 এ । যদি কিছু পরিষ্কার হয় না, বা সত্যই ভুল হয়, বা যদি আপনি আপনার ব্যবহারের ক্ষেত্রে প্রযোজ্য কোনও সমাধান খুঁজে না পান, তবে দয়া করে কোনও সম্পাদনার পরামর্শ দিতে, মন্তব্যগুলিতে স্পষ্টির জন্য অনুরোধ করতে বা একটি নতুন প্রশ্ন খোলার জন্য নির্দ্বিধায় দ্বিধায় থাকুন .... প্রযোজ্য ।

এখানে কিছু প্রচলিত মূর্খতার একটি পরিচয় দেওয়া রয়েছে (এরপরে চার আইডিয়াম হিসাবে পরিচিত) আমরা প্রায়শই পুনরায় দেখা করব

  1. DataFrame.loc- লেবেল দ্বারা নির্বাচনের জন্য একটি সাধারণ সমাধান (+ pd.IndexSliceআরও জটিল জটিল অ্যাপ্লিকেশনগুলির জন্য টুকরোযুক্ত)

  2. DataFrame.xs - সিরিজ / ডেটাফ্রেম থেকে একটি নির্দিষ্ট ক্রস বিভাগটি বের করুন।

  3. DataFrame.query- স্লাইসিং এবং / অথবা ফিল্টারিং অপারেশনগুলি গতিশীলভাবে নির্দিষ্ট করুন (যেমন গতিবেগের সাথে মূল্যায়ন করা হয় এমন একটি এক্সপ্রেশন হিসাবে others অন্যের তুলনায় কিছু পরিস্থিতিতে বেশি প্রযোজ্য Also ডক্সের এই বিভাগটিও দেখুন গতিবেগের সাথে Multi মাল্টিআইডেক্সগুলিতে অনুসন্ধানের জন্য ।

  4. ব্যবহার করে উত্পন্ন মুখোশ দিয়ে বুলিয়ান সূচীকরণ MultiIndex.get_level_values(প্রায়শই এটির সাথে একত্রে)Index.isin বিশেষত একাধিক মান সহ ফিল্টারিংয়ের সময়) when এটি কিছু পরিস্থিতিতে বেশ কার্যকর।

প্রদত্ত পরিস্থিতিতে কী কী প্রয়োগ করা যেতে পারে সে সম্পর্কে আরও ভাল ধারণা অর্জনের জন্য ফোর আইডিয়ামগুলির শর্তে বিভিন্ন কাটা এবং ফিল্টারিং সমস্যাগুলি দেখার পক্ষে উপকারী হবে। এটি বোঝার জন্য এটি খুব গুরুত্বপূর্ণ যে সমস্ত প্রতিমাবাদকরা প্রতিটি পরিস্থিতিতে সমানভাবে (যদি আদৌ) কাজ করবে না। যদি কোনও প্রতিমাটি নীচের সমস্যার সম্ভাব্য সমাধান হিসাবে তালিকাভুক্ত না করা হয়, তার অর্থ হ'ল আইডিয়ামটি কার্যকরভাবে সেই সমস্যায় প্রয়োগ করা যাবে না।


প্রশ্ন 1

"একটি" স্তর "এক" থাকা সারিগুলি কীভাবে নির্বাচন করব?

         col
one two     
a   t      0
    u      1
    v      2
    w      3

আপনি locবেশিরভাগ পরিস্থিতিতে প্রযোজ্য সাধারণ উদ্দেশ্যে সমাধান হিসাবে ব্যবহার করতে পারেন :

df.loc[['a']]

এই মুহুর্তে, যদি আপনি পান

TypeError: Expected tuple, got str

এর অর্থ আপনি পান্ডার একটি পুরানো সংস্করণ ব্যবহার করছেন। আপগ্রেড করার বিষয়টি বিবেচনা করুন! অন্যথায়, ব্যবহার করুন df.loc[('a', slice(None)), :]

বিকল্পভাবে, আপনি xsএখানে ব্যবহার করতে পারেন , যেহেতু আমরা একটি একক ক্রস বিভাগ বের করছি। levelsএবং axisযুক্তিগুলি নোট করুন (যুক্তিসঙ্গত ডিফল্টগুলি এখানে অনুমান করা যায়)।

df.xs('a', level=0, axis=0, drop_level=False)
# df.xs('a', drop_level=False)

এখানে, ফলাফলটিতে "ওয়ান" স্তরটি (যে স্তরের উপরে আমরা কাটাছি) নামা থেকে নিরস্ত drop_level=Falseকরার জন্য যুক্তিটি প্রয়োজনীয় xs

তবুও এখানে অন্য একটি বিকল্প ব্যবহার করা হচ্ছে query:

df.query("one == 'a'")

যদি সূচকের কোনও নাম না থাকে তবে আপনার কোয়েরি স্ট্রিংটি হতে হবে "ilevel_0 == 'a'"

শেষ অবধি get_level_values:

df[df.index.get_level_values('one') == 'a']
# If your levels are unnamed, or if you need to select by position (not label),
# df[df.index.get_level_values(0) == 'a']

অতিরিক্তভাবে, আমি কীভাবে আউটপুটে "এক" স্তরটি ফেলে দিতে সক্ষম হব?

     col
two     
t      0
u      1
v      2
w      3

এটি সহজেই হয় ব্যবহার করে করা যেতে পারে

df.loc['a'] # Notice the single string argument instead the list.

অথবা,

df.xs('a', level=0, axis=0, drop_level=True)
# df.xs('a')

লক্ষ্য করুন যে আমরা drop_levelআর্গুমেন্টটি বাদ দিতে পারি (এটি Trueডিফল্ট হিসাবে ধরে নেওয়া হয় )।

দ্রষ্টব্য
আপনি খেয়াল করতে পারেন যে একটি ফিল্টার করা ডেটা ফ্রেমে এখনও সমস্ত স্তর থাকতে পারে, এমনকি যদি ডেটা ফ্রেম প্রিন্ট করার সময় তারা না দেখায়। উদাহরণ স্বরূপ,

v = df.loc[['a']]
print(v)
         col
one two     
a   t      0
    u      1
    v      2
    w      3

print(v.index)
MultiIndex(levels=[['a', 'b', 'c', 'd'], ['t', 'u', 'v', 'w']],
           labels=[[0, 0, 0, 0], [0, 1, 2, 3]],
           names=['one', 'two'])

আপনি এই স্তরগুলি ব্যবহার করে পরিত্রাণ পেতে পারেন MultiIndex.remove_unused_levels:

v.index = v.index.remove_unused_levels()

print(v.index)
MultiIndex(levels=[['a'], ['t', 'u', 'v', 'w']],
           labels=[[0, 0, 0, 0], [0, 1, 2, 3]],
           names=['one', 'two'])

প্রশ্ন 1 বি

"দুই" স্তরের "t" মান দিয়ে আমি কীভাবে সমস্ত সারি স্লাইস করব?

         col
one two     
a   t      0
b   t      4
    t      8
d   t     12

স্বজ্ঞাতভাবে, আপনি জড়িত কিছু চাইবেন slice():

df.loc[(slice(None), 't'), :]

ইট জাস্ট ওয়ার্কস! ™ তবে এটি আটকানো। আমরা pd.IndexSliceএখানে এপিআই ব্যবহার করে আরও প্রাকৃতিক স্লাইসিং সিনট্যাক্সটি সহজ করতে পারি ।

idx = pd.IndexSlice
df.loc[idx[:, 't'], :]

এটি অনেক, অনেক ক্লিনার।

দ্রষ্টব্য
কেন :কলামগুলি জুড়ে পিছনের স্লাইস প্রয়োজন? এটি কারণ, locউভয় অক্ষ ( axis=0বা axis=1) বরাবর নির্বাচন এবং স্লাইস করতে ব্যবহার করা যেতে পারে । কোন অক্ষটি কাটাতে হবে তা স্পষ্ট করে পরিষ্কার না করেই, অপারেশনটি দ্ব্যর্থক হয়ে যায়। এর বড় লাল বাক্সটি দেখুনটুকরো টুকরো ডকুমেন্টেশনে

আপনি যদি অস্পষ্টতার কোনও ছায়া মুছতে চান তবে locএকটি axis প্যারামিটার গ্রহণ করে :

df.loc(axis=0)[pd.IndexSlice[:, 't']]

axisপ্যারামিটার ব্যতীত (অর্থাত্ কেবল কাজ করে df.loc[pd.IndexSlice[:, 't']]), স্লাইসিংগুলি কলামগুলিতে রয়েছে বলে ধরে নেওয়া হয় এবং কKeyError এবং এই পরিস্থিতিতে উত্থাপিত হবে।

এটি স্লাইসারগুলিতে নথিভুক্ত করা হয় । এই পোস্টের উদ্দেশ্যে, তবে, আমরা স্পষ্টভাবে সমস্ত অক্ষগুলি নির্দিষ্ট করব।

সাথে xs, এটা হয়

df.xs('t', axis=0, level=1, drop_level=False)

সাথে query, এটা হয়

df.query("two == 't'")
# Or, if the first level has no name, 
# df.query("ilevel_1 == 't'") 

এবং অবশেষে, সাথে get_level_values, আপনি করতে পারেন

df[df.index.get_level_values('two') == 't']
# Or, to perform selection by position/integer,
# df[df.index.get_level_values(1) == 't']

সমস্ত একই প্রভাব।


প্রশ্ন 2

"এক" স্তরের আইটেম "বি" এবং "ডি" এর সাথে সম্পর্কিত সারিগুলি আমি কীভাবে নির্বাচন করতে পারি?

         col
one two     
b   t      4
    u      5
    v      6
    w      7
    t      8
d   w     11
    t     12
    u     13
    v     14
    w     15

লোক ব্যবহার করে, এটি একটি তালিকা নির্দিষ্ট করে অনুরূপ ফ্যাশনে করা হয়।

df.loc[['b', 'd']]

"বি" এবং "ডি" নির্বাচন করার উপরের সমস্যাটি সমাধান করার জন্য, আপনি এগুলিও ব্যবহার করতে পারেন query:

items = ['b', 'd']
df.query("one in @items")
# df.query("one == @items", parser='pandas')
# df.query("one in ['b', 'd']")
# df.query("one == ['b', 'd']", parser='pandas')

দ্রষ্টব্য
হ্যাঁ, ডিফল্ট পার্সারটি হ'ল 'pandas', তবে এই সিনট্যাক্সটি হাইলাইট করা গুরুত্বপূর্ণ যে প্রচলিতভাবে পাইথন নয়। পান্ডাস পার্সার প্রকাশের থেকে কিছুটা আলাদা পার্স গাছ উত্পন্ন করে। কিছু অপারেশন নির্দিষ্ট করার জন্য আরও স্বজ্ঞাত করতে এটি করা হয়। আরও তথ্যের জন্য, দয়া করে pd.eval () ব্যবহার করে পান্ডাগুলিতে ডায়নামিক এক্সপ্রেশন মূল্যায়ন সম্পর্কিত আমার পোস্টটি পড়ুন ।

এবং, সঙ্গে get_level_values+ + Index.isin:

df[df.index.get_level_values("one").isin(['b', 'd'])]

প্রশ্ন 2 বি

"টি" এবং "ডাব্লু" স্তরের "দুই" স্তরের সাথে সম্পর্কিত সমস্ত মান আমি কীভাবে পাব?

         col
one two     
a   t      0
    w      3
b   t      4
    w      7
    t      8
d   w     11
    t     12
    w     15

সাথে loc, এটি শুধুমাত্র সাথে জড়িত হয়েই সম্ভব pd.IndexSlice

df.loc[pd.IndexSlice[:, ['t', 'w']], :] 

প্রথম কোলন :মধ্যে pd.IndexSlice[:, ['t', 'w']]উপায়ে প্রথম স্তরের জুড়ে যেভাবেই করতে। অনুসন্ধানের স্তরের গভীরতা বাড়ার সাথে সাথে আপনাকে আরও স্লাইস উল্লেখ করতে হবে, প্রতি স্তরে প্রতিটি কেটে টুকরো টুকরো করা হচ্ছে। তবে, কাটা কাটানোর পরেও আপনাকে আরও স্তর নির্দিষ্ট করতে হবে না ।

সাথে query, এই হয়

items = ['t', 'w']
df.query("two in @items")
# df.query("two == @items", parser='pandas') 
# df.query("two in ['t', 'w']")
# df.query("two == ['t', 'w']", parser='pandas')

সহ get_level_valuesএবং Index.isin(উপরে অনুরূপ):

df[df.index.get_level_values('two').isin(['t', 'w'])]

প্রশ্ন 3

আমি ক্রস বিভাগটি কীভাবে পুনরুদ্ধার করব, অর্থাত্, একটি একক সারি যা থেকে সূচকের জন্য নির্দিষ্ট মান রয়েছে df? বিশেষত, আমি ('c', 'u')প্রদত্ত ক্রস বিভাগটি কীভাবে পুনরুদ্ধার করব

         col
one two     
c   u      9

locকীগুলির একটি টিপল নির্দিষ্ট করে ব্যবহার করুন :

df.loc[('c', 'u'), :]

অথবা,

df.loc[pd.IndexSlice[('c', 'u')]]

দ্রষ্টব্য
এই মুহুর্তে, আপনি PerformanceWarningএটির মতো দেখতে পারা যেতে পারেন:

PerformanceWarning: indexing past lexsort depth may impact performance.

এর অর্থ হ'ল আপনার সূচিটি সাজানো হয়নি। পান্ডগুলি সর্বোত্তম অনুসন্ধান এবং পুনরুদ্ধারের জন্য সূচিটি সাজানো হচ্ছে (এই ক্ষেত্রে, অভিধান হিসাবে, যেহেতু আমরা স্ট্রিং মানগুলি নিয়ে কাজ করছি) উপর নির্ভর করে। একটি দ্রুত ফিক্সটি হ'ল অগ্রিম ব্যবহার করে আপনার ডেটাফ্রেমকে সাজানোDataFrame.sort_index । আপনি যদি এই জাতীয় একাধিক প্রশ্ন করার চেষ্টা করে থাকেন: পারফরম্যান্সের দিক থেকে এটি বিশেষত কাম্য:

df_sort = df.sort_index()
df_sort.loc[('c', 'u')]

আপনি ব্যবহার করতে পারেন MultiIndex.is_lexsorted() সূচকটি বাছাই করা হয়েছে কিনা তা যাচাই করতে । এই ফাংশনটি ফেরত দেয় Trueবা Falseতদনুসারে। অতিরিক্ত বাছাই করার পদক্ষেপ প্রয়োজন কিনা তা নির্ধারণ করতে আপনি এই ফাংশনটিতে কল করতে পারেন।

এর সাথে xs, এটি আবার অন্য যুক্তিগুলির যথাযথ ডিফল্টে সেট করে প্রথম আর্গুমেন্ট হিসাবে কেবল একটি একক টুপল কেটে যাচ্ছে:

df.xs(('c', 'u'))

এর সাথে query, জিনিসগুলি কিছুটা আড়ষ্ট হয়ে ওঠে:

df.query("one == 'c' and two == 'u'")

আপনি এখন দেখতে পাচ্ছেন যে এটি সাধারণকরণ করা তুলনামূলকভাবে কঠিন হতে চলেছে। তবে এই বিশেষ সমস্যার জন্য এখনও ঠিক আছে।

একাধিক স্তরের বিস্তৃত অ্যাক্সেস সহ, get_level_valuesএখনও ব্যবহার করা যেতে পারে, তবে এটি প্রস্তাবিত নয়:

m1 = (df.index.get_level_values('one') == 'c')
m2 = (df.index.get_level_values('two') == 'u')
df[m1 & m2]

প্রশ্ন 4

আমি দুটি সারি কীভাবে নির্বাচন করব ('c', 'u')এবং ('a', 'w')?

         col
one two     
c   u      9
a   w      3

সহ loc, এটি এখনও এতটা সহজ:

df.loc[[('c', 'u'), ('a', 'w')]]
# df.loc[pd.IndexSlice[[('c', 'u'), ('a', 'w')]]]

এর সাথে query, আপনার ক্রস বিভাগ এবং স্তরগুলিকে পুনরাবৃত্তি করে গতিশীলভাবে একটি কোয়েরি স্ট্রিং তৈরি করতে হবে:

cses = [('c', 'u'), ('a', 'w')]
levels = ['one', 'two']
# This is a useful check to make in advance.
assert all(len(levels) == len(cs) for cs in cses) 

query = '(' + ') or ('.join([
    ' and '.join([f"({l} == {repr(c)})" for l, c in zip(levels, cs)]) 
    for cs in cses
]) + ')'

print(query)
# ((one == 'c') and (two == 'u')) or ((one == 'a') and (two == 'w'))

df.query(query)

100% সুপারিশ করবেন না! তবে এটা সম্ভব।


প্রশ্ন 5

"স্তরের" এক "বা" টি "স্তরের" টি "এর সাথে সম্পর্কিত সমস্ত সারি কীভাবে পুনরুদ্ধার করব?

         col
one two     
a   t      0
    u      1
    v      2
    w      3
b   t      4
    t      8
d   t     12

locনির্ভুলতা নিশ্চিত করার এবং কোডের স্পষ্টতা বজায় রাখার সাথে এটি করা আসলে খুব কঠিন । df.loc[pd.IndexSlice['a', 't']]ভুল, এটি ব্যাখ্যা করা হয় df.loc[pd.IndexSlice[('a', 't')]](অর্থাত্, একটি ক্রস বিভাগ নির্বাচন করে)। pd.concatপ্রতিটি লেবেল আলাদাভাবে হ্যান্ডেল করার জন্য আপনি কোনও সমাধানের কথা ভাবতে পারেন :

pd.concat([
    df.loc[['a'],:], df.loc[pd.IndexSlice[:, 't'],:]
])

         col
one two     
a   t      0
    u      1
    v      2
    w      3
    t      0   # Does this look right to you? No, it isn't!
b   t      4
    t      8
d   t     12

তবে আপনি দেখতে পাবেন যে সারিগুলির একটির সদৃশ হয়ে গেছে। এটি কারণ এই সারিটি উভয় কাটা শর্তকেই সন্তুষ্ট করেছিল এবং তাই দু'বার প্রদর্শিত হয়েছিল। পরিবর্তে আপনার এটি করা দরকার

v = pd.concat([
        df.loc[['a'],:], df.loc[pd.IndexSlice[:, 't'],:]
])
v[~v.index.duplicated()]

তবে যদি আপনার ডেটাফ্রেমে সহজাতভাবে সদৃশ সূচকগুলি থাকে (যা আপনি চান) তবে এটি এগুলি ধরে রাখবে না। চরম সতর্কতার সাথে ব্যবহার করুন

সহ query, এটি নির্বোধ সহজ:

df.query("one == 'a' or two == 't'")

সহ get_level_values, এটি এখনও সহজ, তবে মার্জিত নয়:

m1 = (df.index.get_level_values('one') == 'a')
m2 = (df.index.get_level_values('two') == 't')
df[m1 | m2] 

প্রশ্ন 6

আমি কীভাবে নির্দিষ্ট ক্রস বিভাগগুলি স্লাইস করতে পারি? "ক" এবং "বি" এর জন্য আমি উপ-স্তরের "ইউ" এবং "ভি" সহ সমস্ত সারি নির্বাচন করতে চাই এবং "ডি" এর জন্য আমি উপ-স্তরের "ডাব্লু" দিয়ে সারি নির্বাচন করতে চাই।

         col
one two     
a   u      1
    v      2
b   u      5
    v      6
d   w     11
    w     15

এটি একটি বিশেষ কেস যা আমি চারটি আইডিয়ামের প্রযোজনীয়তা বুঝতে সাহায্য করেছি - এটি এমন একটি ক্ষেত্রে যেখানে এর কোনওটিই কার্যকরভাবে কাজ করবে না, যেহেতু কাটা খুব নির্দিষ্ট, এবং কোনও আসল নিদর্শন অনুসরণ করে না।

সাধারণত, এই জাতীয় সমস্যাগুলি কাটানোর জন্য কীগুলির একটি তালিকা স্পষ্টভাবে পাস করা প্রয়োজন loc। এটি করার একটি উপায় হল:

keys = [('a', 'u'), ('a', 'v'), ('b', 'u'), ('b', 'v'), ('d', 'w')]
df.loc[keys, :]

আপনি যদি কিছু টাইপিং সংরক্ষণ করতে চান, আপনি বুঝতে পারবেন যে "ক", "বি" এবং এর সুবলভেল কাটানোর একটি প্যাটার্ন রয়েছে, তাই আমরা কাটা টাস্কটিকে দুটি অংশে এবং concatফলাফলকে পৃথক করতে পারি :

pd.concat([
     df.loc[(('a', 'b'), ('u', 'v')), :], 
     df.loc[('d', 'w'), :]
   ], axis=0)

"এ" এবং "বি" এর জন্য স্লাইসিং স্পেসিফিকেশনটি কিছুটা পরিষ্কার, (('a', 'b'), ('u', 'v'))কারণ একই উপ-স্তরগুলি সূচীকরণ করা প্রতিটি স্তরের জন্য একই।


প্রশ্ন 7

"দুই" স্তরের মান 5 এর চেয়ে বেশি যেখানে আমি কীভাবে সমস্ত সারি পাব?

         col
one two     
b   7      4
    9      5
c   7     10
d   6     11
    8     12
    8     13
    6     15

এটি ব্যবহার করে করা যেতে পারে query,

df2.query("two > 5")

এবং get_level_values

df2[df2.index.get_level_values('two') > 5]

দ্রষ্টব্য
এই উদাহরণের অনুরূপ, আমরা এই নির্মাণগুলি ব্যবহার করে যেকোনো স্বেচ্ছাসেবীর অবস্থার উপর ভিত্তি করে ফিল্টার করতে পারি। সাধারণভাবে, এটা যে মনে রাখা দরকারী locএবং xsলেবেল-ভিত্তিক ইন্ডেক্স জন্য বিশেষভাবে তৈরী করছেন, queryএবং get_level_valuesফিল্টারিং জন্য সাধারণ শর্তসাপেক্ষ মুখোশ নির্মাণের জন্য সহায়ক।


বোনাস প্রশ্ন

আমার যদি MultiIndex কলামটি টুকরো টুকরো করা দরকার ?

প্রকৃতপক্ষে, বেশিরভাগ সমাধান এখানে কলামগুলিতেও সামান্য পরিবর্তন সহ প্রযোজ্য। বিবেচনা:

np.random.seed(0)
mux3 = pd.MultiIndex.from_product([
        list('ABCD'), list('efgh')
], names=['one','two'])

df3 = pd.DataFrame(np.random.choice(10, (3, len(mux))), columns=mux3)
print(df3)

one  A           B           C           D         
two  e  f  g  h  e  f  g  h  e  f  g  h  e  f  g  h
0    5  0  3  3  7  9  3  5  2  4  7  6  8  8  1  6
1    7  7  8  1  5  9  8  9  4  3  0  3  5  0  2  3
2    8  1  3  3  3  7  0  1  9  9  0  4  7  3  2  7

এই কলামগুলির সাথে কাজ করার জন্য ফোর আইডিয়ামগুলিতে আপনাকে নিম্নলিখিত পরিবর্তনগুলি করতে হবে।

  1. সাথে স্লাইস করতে loc, ব্যবহার করুন

    df3.loc[:, ....] # Notice how we slice across the index with `:`. 

    বা,

    df3.loc[:, pd.IndexSlice[...]]
  2. ব্যবহার করার জন্য xsউপযুক্ত হিসেবে শুধু একটি আর্গুমেন্ট পাস axis=1

  3. আপনি সরাসরি ব্যবহার করে কলাম স্তরের মানগুলি অ্যাক্সেস করতে পারেন df.columns.get_level_values। এর পরে আপনার মতো কিছু করা দরকার

    df.loc[:, {condition}] 

    যেখানে {condition}ব্যবহার করে কিছু শর্ত নির্মিত হয় columns.get_level_values

  4. ব্যবহার করার জন্য query, আপনার একমাত্র বিকল্পটি হ'ল সূচকগুলিতে স্থানান্তর, ক্যোয়ারী এবং আবার স্থানান্তর:

    df3.T.query(...).T

    প্রস্তাবিত নয়, অন্যান্য 3 টি বিকল্পের মধ্যে একটি ব্যবহার করুন।


5

সম্প্রতি আমি এমন একটি ব্যবহারের কেস পেয়েছি যেখানে আমার কাছে 3+ স্তরের মাল্টি-ইনডেক্স ডেটাফ্রেম ছিল যাতে আমি যে ফলাফলগুলি সন্ধান করছিলাম তার উপরের সমাধানগুলি আমি কোনওরকম করতে পারিনি। উপরের সমাধানগুলি অবশ্যই আমার ব্যবহারের ক্ষেত্রে কাজ করে এবং এটি বেশ কয়েকটি ক্ষেত্রে চেষ্টা করেছিলাম, তবে আমি যে সময় পেয়েছি তার সাথে সেগুলি কাজে লাগাতে পারিনি।

আমি বিশেষজ্ঞের থেকে অনেক দূরে, তবে আমি এমন একটি সমাধান পেয়েছি যা উপরে বর্ণিত উত্তরের উত্তরে তালিকাভুক্ত ছিল না in আমি কোনও গ্যারান্টি দিচ্ছি না যে সমাধানগুলি কোনওভাবেই সর্বোত্তম are

উপরের প্রশ্ন # 6 এর কিছুটা আলাদা ফলাফল পাওয়ার জন্য এটি একটি ভিন্ন উপায়। (এবং সম্ভবত অন্যান্য প্রশ্নও)

বিশেষত আমি খুঁজছিলাম:

  1. সূচকের এক স্তর থেকে দুটি + মান এবং সূচকের অন্য স্তর থেকে একক মান চয়ন করার উপায় এবং
  2. ডাটাফ্রেম আউটপুটে পূর্বের ক্রিয়াকলাপ থেকে সূচক মানগুলি ছেড়ে যাওয়ার একটি উপায়।

গিয়ার্সে একটি বানর রেঞ্চ হিসাবে (তবে সম্পূর্ণ স্থিরযোগ্য):

  1. সূচিগুলি নামহীন ছিল।

খেলনা ডেটাফ্রেমে নীচে:

    index = pd.MultiIndex.from_product([['a','b'],
                               ['stock1','stock2','stock3'],
                               ['price','volume','velocity']])

    df = pd.DataFrame([1,2,3,4,5,6,7,8,9,
                      10,11,12,13,14,15,16,17,18], 
                       index)

                        0
    a stock1 price      1
             volume     2
             velocity   3
      stock2 price      4
             volume     5
             velocity   6
      stock3 price      7
             volume     8
             velocity   9
    b stock1 price     10
             volume    11
             velocity  12
      stock2 price     13
             volume    14
             velocity  15
      stock3 price     16
             volume    17
             velocity  18

নিচের কাজগুলি অবশ্যই ব্যবহার করে:

    df.xs(('stock1', 'velocity'), level=(1,2))

        0
    a   3
    b  12

তবে আমি অন্যরকম ফলাফল চেয়েছিলাম, সুতরাং সেই ফলাফলটি পাওয়ার জন্য আমার পদ্ধতিটি ছিল:

   df.iloc[df.index.isin(['stock1'], level=1) & 
           df.index.isin(['velocity'], level=2)] 

                        0
    a stock1 velocity   3
    b stock1 velocity  12

এবং যদি আমি এক স্তর থেকে দুটি + মান এবং অন্য স্তর থেকে একক (বা 2+) মান চাইতাম:

    df.iloc[df.index.isin(['stock1','stock3'], level=1) & 
            df.index.isin(['velocity'], level=2)] 

                        0
    a stock1 velocity   3
      stock3 velocity   9
    b stock1 velocity  12
      stock3 velocity  18

উপরের পদ্ধতিটি সম্ভবত খানিকটা আড়ম্বরপূর্ণ, তবে আমি এটি পেয়েছিলাম যে এটি আমার প্রয়োজনীয়তা পূরণ করেছে এবং বোনাস হিসাবে আমার পক্ষে বুঝতে এবং পড়া সহজ ছিল।


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