पांडा श्रृंखला में तत्व का सूचकांक खोजें


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
यहाँ परेशानी यह है कि खोजे जा रहे तत्व को वास्तव में सूची में रखा गया है। यह एक bummer पांडा है लगता है एक ऑपरेशन में बनाया नहीं है।
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 अग्रिम में है। आप इसे (myseries == 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स्थितियों का खुलासा करेगा जो आप यहाँ देख सकते हैं ।
18

1
सावधान, यदि कोई तत्व इस स्थिति से मेल नहीं खाता है, तब argmaxभी 0 (वापसी के बजाय बाहर) को वापस करेगा।
cs95

8

मैं यहाँ सभी उत्तरों से प्रभावित हूँ। यह एक नया जवाब नहीं है, बस इन सभी तरीकों के समय को संक्षेप में प्रस्तुत करने का प्रयास है। मैंने 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)

@ जेफ का जवाब सबसे तेज लगता है - हालांकि यह डुप्लिकेट को संभालता नहीं है।

सुधार : क्षमा करें, मुझे एक याद आया, सूची सूचकांक विधि का उपयोग करके @Alex Spangher का समाधान अब तक का सबसे तेज़ है।

अद्यतन : @ EliadL का उत्तर जोड़ा गया।

उम्मीद है की यह मदद करेगा।

कमाल है कि इस तरह के एक सरल ऑपरेशन के लिए ऐसे जटिल समाधानों की आवश्यकता होती है और कई इतने धीमे होते हैं। 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 myseries में मान है:

(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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.