programing

판다 시리즈에서 원소 색인 찾기

goodcopy 2023. 1. 20. 16:23
반응형

판다 시리즈에서 원소 색인 찾기

나는 이것이 매우 기본적인 질문이라는 것을 알지만 어떤 이유에서인지 답을 찾을 수 없다.Python Pander에서 Series의 특정 요소의 인덱스를 얻으려면 어떻게 해야 합니까?(첫 번째 발생으로 충분합니다.)

예를 들어, 다음과 같은 것을 원합니다.

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)

하지만 더 나은 방법이 있을 것 같아요있어?

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

더 나은 방법이 있어야 한다는 것은 인정하지만, 적어도 오브젝트를 통해 반복과 루프를 방지하고 오브젝트를 C레벨로 이동합니다.

인덱스로 변환하는 경우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

Viktor가 지적한 바와 같이 인덱스를 작성하기 위한 일회성 생성 오버헤드가 있습니다(예를 들어 인덱스를 실제로 조작할 때 발생합니다).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

나는 여기에 있는 모든 대답에 감명받았다.이는 새로운 답변이 아니라 이들 모든 방식의 타이밍을 요약하려는 시도입니다.나는 25개의 요소가 있는 시리즈의 경우를 고려했고 인덱스에 어떤 값도 포함할 수 있는 일반적인 경우를 가정했다. 그리고 당신은 시리즈가 끝날 무렵에 있는 검색 값에 대응하는 인덱스 값을 원한다.

다음은 Pidson 버전 1.4.0이 설치된 Python 3.9.10의 2012 Mac Mini에 대한 속도 테스트입니다.

In [1]: import pandas as pd

In [2]: import numpy as np

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

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

In [5]: assert(myseries[21] == 150)

In [6]: %timeit myseries[myseries == 150].index[0]
179 µs ± 891 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

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

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

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

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

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

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

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

In [14]: %timeit dict(zip(myseries.values, myseries.index))[150]
9.89 µs ± 79.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [15]: %timeit {v: k for k, v in myseries.items()}[150]
9.99 µs ± 67 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

@Jeff의 답변이 가장 빠른 것 같습니다.중복에 대응하고 있지는 않지만.

수정:죄송합니다. 1개를 놓쳤습니다.목록 인덱스 방식을 사용하는 @Alex Spangher 솔루션이 가장 빠릅니다.

업데이트: @EliadL의 답변이 추가되었습니다.

이게 도움이 됐으면 좋겠다.

이렇게 간단한 조작에는 이러한 복잡한 솔루션이 필요하며 많은 작업이 매우 느리다니 놀랍습니다.경우에 따라서는 25의 연속 값을 찾기 위해 0.5밀리초가 넘는 경우도 있습니다.

2022-02-18 갱신

모든 타이밍을 Panda 최신 버전과 Python 3.9로 업데이트했습니다.오래된 컴퓨터에서도 이전 테스트(버전 0.25.3)에 비해 모든 타이밍이 대폭(10~70%) 감소했습니다.

플러스: 사전을 활용하여 두 가지 메서드를 추가했습니다.

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']

마찬가지로 불만족스럽지만 이를 위한 또 다른 방법은 다음과 같습니다.

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

numpy를 사용하면 값에서 찾을 수 있는 다양한 정보를 얻을 수 있습니다.

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)

그러면 myseries에서 7이 값인 일련의 외설사항을 포함하는 하나의 요소 태플이 반환됩니다.

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

Series.idxmax()를 사용할 수 있습니다.

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

이것이 제가 찾을 수 있는 가장 네이티브하고 확장성이 뛰어난 접근법입니다.

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

>>> myindex[7]
3

>>> myindex[[7, 5, 7]]
7    3
5    4
7    3
dtype: int64

아직 언급되지 않은 다른 방법은 tolist 방식입니다.

myseries.tolist().index(7)

값이 시리즈에 있다고 가정하면 올바른 인덱스를 반환해야 합니다.

값이 여러 인덱스에서 발생하는 경우가 많습니다.

>>> 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')

는 품격을 있다.Index라는 기능을 가진get_loc

index(인덱스)
된 번호가시퀀스에 )
array인덱스에 (복수 인덱스에 있는 경우)

예:

import pandas as pd

>>> mySer = pd.Series([1, 3, 8, 10, 13])
>>> pd.Index(mySer).get_loc(10)  # Returns index
3  # Index of 10 in series

>>> mySer = pd.Series([1, 3, 8, 10, 10, 10, 13])
>>> pd.Index(mySer).get_loc(10)  # Returns slice
slice(3, 6, None)  # 10 occurs at index 3 (included) to 6 (not included)


# If the data is not in sequence then it would return an array of bool's.
>>> mySer = pd.Series([1, 10, 3, 8, 10, 10, 10, 13, 10])
>>> pd.Index(mySer).get_loc(10)
array([False, True, False, False, True, True, False, True])

그 밖에도 여러 가지 선택지가 있지만, 저는 그것이 매우 간단하다는 것을 알았습니다.

df.index 메서드는 정확한 행 번호를 찾는 데 도움이 됩니다.

my_fl2=(df['ConvertedCompYearly'] == 45241312 )
print (df[my_fl2].index)

   
Name: ConvertedCompYearly, dtype: float64
Int64Index([66910], dtype='int64')

언급URL : https://stackoverflow.com/questions/18327624/find-elements-index-in-pandas-series

반응형