পান্ডাস সিরিজে উপাদানগুলির সূচকটি সন্ধান করুন


154

আমি জানি এটি একটি খুব প্রাথমিক প্রশ্ন তবে কিছু কারণে আমি উত্তর খুঁজে পাচ্ছি না। পাইথন পান্ডসে সিরিজের নির্দিষ্ট উপাদানের সূচকটি কীভাবে পাব? (প্রথম ঘটনাটি যথেষ্ট হবে)

অর্থাৎ, আমি এর মতো কিছু চাই:

import pandas as pd
myseries = pd.Series([1,4,0,7,5], index=[0,1,2,3,4])
print myseries.find(7) # should output 3

অবশ্যই, একটি লুপ দিয়ে এই জাতীয় পদ্ধতির সংজ্ঞা দেওয়া সম্ভব:

def find(s, el):
    for i in s.index:
        if s[i] == el: 
            return i
    return None

print find(myseries, 7)

তবে আমি ধরে নিচ্ছি এর চেয়ে ভাল উপায় আর হওয়া উচিত। আছে?

উত্তর:


199
>>> myseries[myseries == 7]
3    7
dtype: int64
>>> myseries[myseries == 7].index[0]
3

যদিও আমি স্বীকার করি যে এটি করার আরও ভাল উপায় হওয়া উচিত তবে এটি কমপক্ষে পুনরাবৃত্তি এবং বস্তুর মধ্য দিয়ে লুপিং এড়ানো এবং এটি সি স্তরে নিয়ে যায়।


12
এখানে সমস্যাটি এটি ধরে নিয়েছে যে উপাদানটি অনুসন্ধান করা হচ্ছে তা আসলে তালিকায় রয়েছে। এটি একটি বোমার পান্ডার সন্ধান অপারেশনটি অন্তর্নির্মিত বলে মনে হচ্ছে না।
jxramos

7
এই সিরিয়ালটি কেবল তখনই কাজ করে যদি আপনার সিরিজে একটি অনুক্রমিক পূর্ণসংখ্যা সূচক থাকে। যদি আপনার সিরিজ সূচক তারিখের সময় হয় তবে এটি কার্যকর হয় না।
অ্যান্ড্রু মেডলিন

43

একটি সূচক রূপান্তর, আপনি ব্যবহার করতে পারেন get_loc

In [1]: myseries = pd.Series([1,4,0,7,5], index=[0,1,2,3,4])

In [3]: Index(myseries).get_loc(7)
Out[3]: 3

In [4]: Index(myseries).get_loc(10)
KeyError: 10

সদৃশ পরিচালনা

In [5]: Index([1,1,2,2,3,4]).get_loc(2)
Out[5]: slice(2, 4, None)

অ-সংগতিপূর্ণ রিটার্ন হলে একটি বুলিয়ান অ্যারে প্রদান করবে

In [6]: Index([1,1,2,1,3,2,4]).get_loc(2)
Out[6]: array([False, False,  True, False, False,  True, False], dtype=bool)

অভ্যন্তরীণভাবে একটি হ্যাশটেবল ব্যবহার করে, তাই দ্রুত

In [7]: s = Series(randint(0,10,10000))

In [9]: %timeit s[s == 5]
1000 loops, best of 3: 203 µs per loop

In [12]: i = Index(s)

In [13]: %timeit i.get_loc(5)
1000 loops, best of 3: 226 µs per loop

ভিক্টর একটা বিষয় চিহ্নিত করেছে, একটি এক সময় সৃষ্টি একটি সূচক তৈরি করতে ওভারহেড হয় (তার যথাযোগ্য যখন আপনি আসলে সূচকের সাথে কিছু, যেমন is_unique)

In [2]: s = Series(randint(0,10,10000))

In [3]: %timeit Index(s)
100000 loops, best of 3: 9.6 µs per loop

In [4]: %timeit Index(s).is_unique
10000 loops, best of 3: 140 µs per loop

1
@ জেফ যদি আপনার আরও আকর্ষণীয় সূচক হয় তবে এটি এত সহজ নয় ... তবে আমি অনুমান করি আপনি কেবল এটি করতে পারেনs.index[_]
অ্যান্ডি হেডেন

11
In [92]: (myseries==7).argmax()
Out[92]: 3

আপনি যদি আগে থেকেই 7 জেনে থাকেন তবে এটি কাজ করে। আপনি এটি (মাইজারিজ == 7) দিয়ে চেক করতে পারেন any

আরও একটি পদ্ধতির (প্রথম জবাবের সাথে খুব মিল) যা একাধিক 7 এর (বা কোনও নয়) এর জন্যও দায়ী

In [122]: myseries = pd.Series([1,7,0,7,5], index=['a','b','c','d','e'])
In [123]: list(myseries[myseries==7].index)
Out[123]: ['b', 'd']

7 জানার বিষয়টি আগাম একটি উপাদান এটি ঠিক আছে। তবে একটি ব্যবহারany চেক আদর্শ নয়, কারণ দ্বৈত পুনরাবৃত্তি প্রয়োজন। একটি দুর্দান্ত পোস্ট অপশন চেক রয়েছে যা এখানেFalse আপনি দেখতে পাচ্ছেন এমন সমস্ত শর্ত উন্মোচন করবে ।
jxramos

1
সাবধান, যদি কোনও উপাদান এই শর্তের সাথে মেলে না, তবে argmaxএখনও 0 (ত্রুটিযুক্ত হওয়ার পরিবর্তে) ফিরে আসবে।
cs95

8

আমি এখানে সমস্ত উত্তর দিয়ে মুগ্ধ। এটি কোনও নতুন উত্তর নয়, কেবলমাত্র এই সমস্ত পদ্ধতির সময় সংক্ষেপের চেষ্টা an আমি 25 টি উপাদান সহ একটি সিরিজের কেস বিবেচনা করেছি এবং সাধারণ কেস ধরে নিয়েছি যেখানে সূচীতে কোনও মান থাকতে পারে এবং আপনি অনুসন্ধানের মানের সাথে সূচকের মানটি চান যা সিরিজের শেষের দিকে থাকে।

পান্ডাস সংস্করণ 0.25.3 সহ পাইথন 3.7-তে একটি 2013 ম্যাকবুক প্রো-এর গতি পরীক্ষা এখানে।

In [1]: import pandas as pd                                                

In [2]: import numpy as np                                                 

In [3]: data = [406400, 203200, 101600,  76100,  50800,  25400,  19050,  12700, 
   ...:          9500,   6700,   4750,   3350,   2360,   1700,   1180,    850, 
   ...:           600,    425,    300,    212,    150,    106,     75,     53, 
   ...:            38]                                                                               

In [4]: myseries = pd.Series(data, index=range(1,26))                                                

In [5]: myseries[21]                                                                                 
Out[5]: 150

In [7]: %timeit myseries[myseries == 150].index[0]                                                   
416 µs ± 5.05 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [8]: %timeit myseries[myseries == 150].first_valid_index()                                        
585 µs ± 32.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [9]: %timeit myseries.where(myseries == 150).first_valid_index()                                  
652 µs ± 23.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [10]: %timeit myseries.index[np.where(myseries == 150)[0][0]]                                     
195 µs ± 1.18 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [11]: %timeit pd.Series(myseries.index, index=myseries)[150]                 
178 µs ± 9.35 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [12]: %timeit myseries.index[pd.Index(myseries).get_loc(150)]                                    
77.4 µs ± 1.41 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [13]: %timeit myseries.index[list(myseries).index(150)]
12.7 µs ± 42.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [14]: %timeit myseries.index[myseries.tolist().index(150)]                   
9.46 µs ± 19.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

@ জেফের উত্তরটি সবচেয়ে দ্রুত বলে মনে হচ্ছে - যদিও এটি সদৃশগুলি পরিচালনা করে না।

সংশোধন : দুঃখিত, আমি একটি মিস করেছি, @ তালিকা অ্যালেক্স স্প্যাংহের তালিকা সূচক পদ্ধতিটি ব্যবহার করে দ্রুততমতম দ্র।

আপডেট : যোগ করেছেন এলিয়াডএল এর উত্তর।

আশাকরি এটা সাহায্য করবে.

আশ্চর্যজনক যে এ জাতীয় সরল ক্রিয়াকলাপের জন্য এই জাতীয় সংশ্লেষযুক্ত সমাধানের প্রয়োজন হয় এবং অনেকগুলি এত ধীর হয়। 25 টি সিরিজের একটি মান খুঁজতে কিছু ক্ষেত্রে অর্ধেক মিলিসেকেন্ডেরও বেশি।


1
ধন্যবাদ। তবে আপনি কি তৈরি হওয়ার পরে পরিমাপ করবেন না myindex, কারণ এটি কেবল একবার তৈরি করা দরকার?
এলিয়াদএল

আপনি এটি তর্ক করতে পারেন তবে এটির মতো এইর জন্য আরও কত চেহারা প্রয়োজন তা নির্ভর করে। myindexআপনি যদি বহুবার অনুসন্ধান করতে যাচ্ছেন তবে এটি কেবল সিরিজটি তৈরি করার উপযুক্ত । এই পরীক্ষার জন্য আমি ধরে নিয়েছিলাম যে এটি কেবল একবারের দরকার হয়েছিল এবং মোট মৃত্যুর সময় কার্যকর ছিল।
বিল

1
এই আজ রাতে কেবল এটির প্রয়োজনে ছুটে এসে একাধিক লুকআপে একই সূচক বস্তুতে .get_lock () ব্যবহার করে মনে হচ্ছে এটি দ্রুত হওয়া উচিত। আমি মনে করি উত্তরের একটি উন্নতি হ'ল উভয়ের জন্য সময় সরবরাহ করা: সূচক তৈরির অন্তর্ভুক্ত এবং এটি তৈরির পরে কেবলমাত্র অনুসন্ধানের অন্য একটি সময়।
রিক

হ্যাঁ, ভাল কথা। @ এলিয়াডল এটিও বলেছে। এটি নির্ভর করে যে কতগুলি অ্যাপ্লিকেশন সিরিজটি স্থির রয়েছে। সিরিজের কোনও মান পরিবর্তন হলে, আপনাকে পুনর্নির্মাণ করতে হবে pd.Index(myseries)। অন্যান্য পদ্ধতির সাথে ন্যায্য হতে আমি ধরে নিয়েছিলাম মূল সিরিজটি শেষ দেখার পরে থেকে পরিবর্তিত হতে পারে।
বিল

5

এটি করার আরেকটি উপায়, যদিও সমানভাবে অসন্তুষ্টিজনক:

s = pd.Series([1,3,0,7,5],index=[0,1,2,3,4])

list(s).index(7)

রিটার্ন: 3

বর্তমান কাজ করা ডেটাসেট ব্যবহার করে সময় পরীক্ষার সময় আমি এটিকে এলোমেলো করে বিবেচনা করি:

[64]:    %timeit pd.Index(article_reference_df.asset_id).get_loc('100000003003614')
10000 loops, best of 3: 60.1 µs per loop

In [66]: %timeit article_reference_df.asset_id[article_reference_df.asset_id == '100000003003614'].index[0]
1000 loops, best of 3: 255 µs per loop


In [65]: %timeit list(article_reference_df.asset_id).index('100000003003614')
100000 loops, best of 3: 14.5 µs per loop

4

আপনি যদি ন্যালি ব্যবহার করেন তবে আপনি যে মূল্য খুঁজে পেয়েছেন তার সূচকের একটি অ্যারে পাবেন:

import numpy as np
import pandas as pd
myseries = pd.Series([1,4,0,7,5], index=[0,1,2,3,4])
np.where(myseries == 7)

এটি সূচিতগুলির একটি অ্যারে সম্বলিত একটি উপাদানের টুপল ফেরত দেয় যেখানে মাইসারিজগুলিতে 7 মান:

(array([3], dtype=int64),)

3

আপনি Series.idxmax () ব্যবহার করতে পারেন

>>> import pandas as pd
>>> myseries = pd.Series([1,4,0,7,5], index=[0,1,2,3,4])
>>> myseries.idxmax()
3
>>> 

5
এটি কেবলমাত্র সূচিটি ফেরত প্রদর্শিত হবে যেখানে সর্বাধিক উপাদান পাওয়া যায়, index of certain elementপ্রশ্নের অনুরোধের মতো কোনও নির্দিষ্ট নয় ।
jxramos

1

এটি করার আরেকটি উপায় যা এখনও উল্লেখ করা হয়নি তা হ'ল টলিস্ট পদ্ধতি:

myseries.tolist().index(7)

সিরিজের মান বিদ্যমান বলে ধরে নিয়ে সঠিক সূচকটি ফিরিয়ে দেওয়া উচিত।


1
@ অ্যালেক্স স্পাঙ্গার 17 সেপ্টেম্বর '14 এ অনুরূপ কিছু প্রস্তাব করেছিলেন। তার উত্তর দেখুন। আমি এখন পরীক্ষার ফলাফলগুলিতে উভয় সংস্করণ যুক্ত করেছি।
বিল

0

প্রায়শই আপনার মান একাধিক সূচকে ঘটে:

>>> myseries = pd.Series([0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1])
>>> myseries.index[myseries == 1]
Int64Index([3, 4, 5, 6, 10, 11], dtype='int64')

0

এটি সর্বাধিক নেটিভ এবং স্কেলযোগ্য পদ্ধতি যা আমি খুঁজে পেলাম:

>>> myindex = pd.Series(myseries.index, index=myseries)

>>> myindex[7]
3

>>> myindex[[7, 5, 7]]
7    3
5    4
7    3
dtype: int64
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.