호출 가능한 Pandas에서 인덱싱 및 선택

8551 단어 pythonpandas
이것은 pandas에서 인덱싱 및 선택에 대한 시리즈의 네 번째 항목입니다. 요약하면 다음과 같습니다.
  • Basic indexing, selecting by label and location
  • Slicing in pandas
  • Selecting by boolean indexing

  • 지금까지의 모든 논의에서 우리는 두 가지 주요 pandas 데이터 구조, SeriesDataFrame에서 데이터를 선택하는 세 가지 주요 방법에 중점을 두었습니다.
  • 배열 인덱싱 연산자 또는 []
  • 인덱스
  • 의 레이블을 사용하여 선택하기 위한 .loc 선택기
  • 위치를 사용하여 선택하기 위한 .iloc 선택기

  • 시리즈의 마지막 항목에서 세 가지 모두 부울 벡터를 인덱서로 사용하여 개체에서 데이터를 선택할 수 있음을 언급했습니다. 콜러블을 전달할 수도 있습니다. 콜러블에 익숙하지 않은 경우 ___call___ 메서드가 있는 함수 또는 객체일 수 있습니다. pandas 선택에 사용되는 경우 호출 가능 항목은 pandas 객체가 될 인수 하나를 가져와 데이터세트에서 데이터를 선택하는 결과를 반환해야 합니다. 왜 이것을 하시겠습니까? 이것이 어떻게 유용할 수 있는지 살펴보겠습니다.

    이 시리즈에서는 Chicago Data Portal 에서 데이터를 가져왔습니다. 이 게시물에서는 도시list of current employees를 잡았습니다. 여기에는 정규직 및 시간제, 급여 및 시간제 데이터가 포함됩니다.

    >>> import pandas as pd
    >>>
    >>> # you should be able to grab this dataset as an unauthenticated user, but you can be rate limited
    >>> # it also only returns 1000 rows (or at least it did for me without an API key)
    >>> df = pd.read_json("https://data.cityofchicago.org/resource/xzkq-xp2w.json")
    >>> df.dtypes
    name object
    job_titles object
    department object
    full_or_part_time object
    salary_or_hourly object
    annual_salary float64
    typical_hours float64
    hourly_rate float64
    dtype: object
    >>> df.describe()
           annual_salary typical_hours hourly_rate
    count 785.000000 215.000000 215.000000
    mean 87307.076637 35.558140 34.706000
    std 20342.094746 8.183932 13.027963
    min 20568.000000 20.000000 3.000000
    25% 76164.000000 40.000000 22.350000
    50% 87006.000000 40.000000 38.350000
    75% 97386.000000 40.000000 44.400000
    max 180000.000000 40.000000 57.040000
    >>> df.shape
    (1000, 8)
    >>> df = df.drop('name', axis=1) # no need to include personal info in this post
    


    간단한 호출 가능



    그래서 우리는 시카고시의 전체 직원 목록의 하위 집합인 일부 데이터를 가지고 있습니다. 전체 데이터 세트는 약 32,000행이어야 합니다.

    몇 가지 예를 제시하기 전에 이 콜러블이 무엇을 해야 하는지 명확히 합시다. 먼저 콜러블은 인덱싱되는 DataFrame 또는 Series인 하나의 인수를 취합니다. 인덱싱에 유효한 값을 반환하는 데 필요한 항목입니다. 이것은 이전 게시물에서 이미 논의한 모든 값일 수 있습니다.

    따라서 배열 인덱싱 연산자를 사용하는 경우 DataFrame에서 단일 열 또는 선택할 열 목록을 전달할 수 있음을 기억할 것입니다.

    >>> def select_job_titles(df):
    ... return "job_titles"
    ...
    >>> df[select_job_titles]
    0 SERGEANT
    1 POLICE OFFICER (ASSIGNED AS DETECTIVE)
    2 CHIEF CONTRACT EXPEDITER
    3 CIVIL ENGINEER IV
    4 CONCRETE LABORER
                            ...
    995 AVIATION SECURITY OFFICER
    996 FIREFIGHTER-EMT
    997 LIBRARIAN IV
    998 HUMAN SERVICE SPECIALIST II
    999 POLICE OFFICER
    Name: job_titles, Length: 1000, dtype: object
    >>> def select_job_titles_typical_hours(df):
    ... return ["job_titles", "typical_hours"]
    ...
    >>> df[select_job_titles_typical_hours].dropna()
                               job_titles typical_hours
    4 CONCRETE LABORER 40.0
    6 TRAFFIC CONTROL AIDE-HOURLY 20.0
    7 ELECTRICAL MECHANIC 40.0
    10 FOSTER GRANDPARENT 20.0
    21 ELECTRICAL MECHANIC (AUTOMOTIVE) 40.0
    .. ... ...
    971 CONSTRUCTION LABORER 40.0
    974 HOISTING ENGINEER 40.0
    977 CONSTRUCTION LABORER 40.0
    988 CONSTRUCTION LABORER 40.0
    991 SANITATION LABORER 40.0
    
    [215 rows x 2 columns]
    


    유효한 인수이기 때문에 부울 인덱서를 반환할 수도 있습니다.

    >>> def select_20_hours_or_less(df):
    ... return df['typical_hours'] <= 20
    ...
    >>> df[select_20_hours_or_less].head(1)
                        job_titles department full_or_part_time salary_or_hourly annual_salary typical_hours hourly_rate
    6 TRAFFIC CONTROL AIDE-HOURLY OEMC P Hourly NaN 20.0 19.86
    

    DataFrame 에서 첫 번째(행 인덱서) 및 두 번째(열 인덱서) 인수 모두에 대해 호출 가능 함수를 사용할 수도 있습니다.

    >>> df.loc[lambda df: df['typical_hours'] <= 20, lambda df: ['job_titles', 'typical_hours']].head()
                          job_titles typical_hours
    6 TRAFFIC CONTROL AIDE-HOURLY 20.0
    10 FOSTER GRANDPARENT 20.0
    91 CROSSING GUARD 20.0
    113 SENIOR COMPANION 20.0
    125 TITLE V PROGRAM TRAINEE I 20.0
    


    하지만 왜?



    좋습니다. 훨씬 더 직접적으로 할 수 있기 때문에 이 모든 것이 불필요해 보입니다. 다른 수준의 리디렉션을 제공하기 위해 별도의 함수를 작성하는 이유는 무엇입니까?

    이 게시물을 작성하기 전에 콜러블 인덱싱을 많이 사용하지 않았다고 생각합니다. 하지만 도움이 되는 한 가지 사용 사례는 제가 항상 하는 일입니다. 어쩌면 당신도 할 수 있습니다.

    평균 시간당 급여가 임계값 미만인 부서를 찾고 싶다고 가정해 보겠습니다. 일반적으로 결과 groupbyDataFrame에 대해 선택기가 뒤에 오는 group by를 수행합니다.

    >>> temp = df.groupby('job_titles').mean()
    >>> temp[temp['hourly_rate'] < 20].head()
                              annual_salary typical_hours hourly_rate
    job_titles
    ALDERMANIC AIDE 41760.0 25.0 14.000
    CROSSING GUARD - PER CBA NaN 20.0 15.195
    CUSTODIAL WORKER NaN 40.0 19.200
    FOSTER GRANDPARENT NaN 20.0 3.000
    HOSPITALITY WORKER NaN 20.0 14.110
    


    그러나 콜러블을 사용하면 임시DataFrame 변수 없이 이 작업을 수행할 수 있습니다.

    >>> df.groupby('job_titles').mean().loc[lambda df: df['hourly_rate'] < 20].head()
                              annual_salary typical_hours hourly_rate
    job_titles
    ALDERMANIC AIDE 41760.0 25.0 14.000
    CROSSING GUARD - PER CBA NaN 20.0 15.195
    CUSTODIAL WORKER NaN 40.0 19.200
    FOSTER GRANDPARENT NaN 20.0 3.000
    HOSPITALITY WORKER NaN 20.0 14.110
    


    한 가지 주의할 점은 이러한 호출 가능 항목에는 특별한 것이 없다는 것입니다. 그들은 여전히 ​​사용하기로 선택한 선택기에 대해 올바른 값을 반환해야 합니다. 예를 들어 loc 다음과 같이 할 수 있습니다.

    >>> df.loc[lambda df: df['department'] == 'CITY COUNCIL'].head(1)
                          job_titles department full_or_part_time salary_or_hourly annual_salary typical_hours hourly_rate
    124 STUDENT INTERN - ALDERMANIC CITY COUNCIL F Hourly NaN 35.0 14.0
    


    하지만 .iloc 에는 인덱스가 없는 부울 벡터가 필요하기 때문에 (the post on boolean indexing 에서 이야기한 것처럼) 할 수 없습니다.

    >>> try:
    ...     df.iloc[lambda df: df['department'] == 'CITY COUNCIL']
    ... except NotImplementedError as nie:
    ...     print(nie)
    ...
    iLocation based boolean indexing on an integer type is not available
    >>> df.iloc[lambda df: (df['department'] == 'CITY COUNCIL').values].head(1)
                          job_titles department full_or_part_time salary_or_hourly annual_salary typical_hours hourly_rate
    124 STUDENT INTERN - ALDERMANIC CITY COUNCIL F Hourly NaN 35.0 14.0
    >>> # or
    >>> df.iloc[lambda df: (df['department'] == 'CITY COUNCIL').to_numpy()].head(1)
                          job_titles department full_or_part_time salary_or_hourly annual_salary typical_hours hourly_rate
    124 STUDENT INTERN - ALDERMANIC CITY COUNCIL F Hourly NaN 35.0 14.0
    


    또한 이 모든 예제에 DataFrame를 사용했지만 Series에서도 작동합니다.

    >>> s[lambda s: s < 30000]
    175 20568.0
    Name: annual_salary, dtype: float64
    


    요약하면 콜러블을 사용한 인덱싱은 임시 변수를 필요로 하는 일부 코드를 압축하기 위한 유연성을 허용합니다. 콜러블 기술에 대해 기억해야 할 점은 콜러블과 동일한 위치에서 수용 가능한 인수인 결과를 반환해야 한다는 것입니다.

    향후 업데이트를 계속 지켜봐 주시기 바랍니다. .where 선발 방식에 대해서는 다음에 이야기할 예정이다.

    게시물Indexing and Selecting in Pandas by Callablewrighters.io에 처음 등장했습니다.

    좋은 웹페이지 즐겨찾기