[python] pandas 데이터 프레임을 여러 열로 필터링하는 방법

단일 열로 데이터 프레임 (df)을 필터링하려면 남성과 여성이 포함 된 데이터를 고려하면 다음을 수행 할 수 있습니다.

males = df[df[Gender]=='Male']

질문 1-데이터가 여러 해에 걸쳐 있고 2014 년에는 남성 만보고 싶었다면 어떻게됩니까?

다른 언어에서는 다음과 같이 할 수 있습니다.

if A = "Male" and if B = "2014" then 

(이 작업을 수행하고 새 데이터 프레임 개체에서 원래 데이터 프레임의 하위 집합을 가져오고 싶습니다 제외)

질문 2. 루프에서이 작업을 수행하고 각 고유 한 연도 및 성별 세트에 대한 데이터 프레임 객체를 생성하는 방법 (예 : 2013- 남성, 2013- 여성, 2014- 남성 및 2014- 여성에 대한 df)

for y in year:

for g in gender:

df = .....



답변

&연산자를 사용 하여 하위 문을 ()다음 으로 래핑하는 것을 잊지 마십시오 .

males = df[(df[Gender]=='Male') & (df[Year]==2014)]

dictfor 루프를 사용 하여 데이터 프레임을 저장하려면 :

from collections import defaultdict
dic={}
for g in ['male', 'female']:
  dic[g]=defaultdict(dict)
  for y in [2013, 2014]:
    dic[g][y]=df[(df[Gender]==g) & (df[Year]==y)] #store the DataFrames to a dict of dict

편집하다:

에 대한 데모 getDF:

def getDF(dic, gender, year):
  return dic[gender][year]

print genDF(dic, 'male', 2014)


답변

필터로 사용하고 하나 이상의 열에 의존하는보다 일반적인 부울 함수의 경우 다음을 사용할 수 있습니다.

df = df[df[['col_1','col_2']].apply(lambda x: f(*x), axis=1)]

여기서 f는 col_1 및 col_2의 모든 요소 쌍 (x1, x2)에 적용되고 원하는 조건 (x1, x2)에 따라 True 또는 False를 반환하는 함수입니다.


답변

pandas 0.13 부터 시작합니다 . 이것이 가장 효율적인 방법입니다.

df.query('Gender=="Male" & Year=="2014" ')


답변

누군가 필터링하는 더 빠른 방법이 무엇인지 궁금해하는 경우 (수락 된 답변 또는 @redreamality의 답변) :

import pandas as pd
import numpy as np

length = 100_000
df = pd.DataFrame()
df['Year'] = np.random.randint(1950, 2019, size=length)
df['Gender'] = np.random.choice(['Male', 'Female'], length)

%timeit df.query('Gender=="Male" & Year=="2014" ')
%timeit df[(df['Gender']=='Male') & (df['Year']==2014)]

100,000 개 행에 대한 결과 :

6.67 ms ± 557 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
5.54 ms ± 536 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

10,000,000 개 행에 대한 결과 :

326 ms ± 6.52 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
472 ms ± 25.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

따라서 결과는 크기와 데이터에 따라 다릅니다. 내 노트북에서는 query()500k 행 후에 더 빨라집니다. 또한 문자열 검색 Year=="2014"에는 불필요한 오버 헤드가 있습니다 ( Year==2014빠름).


답변

queryin을 사용하여 고유 한 필터 함수를 만들 수 있습니다 pandas. 여기 df에서 모든 kwargs매개 변수를 기준 으로 결과를 필터링 할 수 있습니다 . kwargs자신의 .NET 용 필터 기능을 얻기 위해 유효성 검사기 ( 필터링) 를 추가하는 것을 잊지 마십시오 df.

def filter(df, **kwargs):
    query_list = []
    for key in kwargs.keys():
        query_list.append(f'{key}=="{kwargs[key]}"')
    query = ' & '.join(query_list)
    return df.query(query)


답변

np.logical_and대체 &(또는 np.logical_or대체 |) 연산자를 사용하여 여러 열 (3 개 이상)로 필터링 할 수 있습니다.

다음은 여러 필드에 대상 값을 제공하는 경우 작업을 수행하는 함수의 예입니다. 다양한 유형의 필터링 및 기타 사항에 맞게 조정할 수 있습니다.

def filter_df(df, filter_values):
    """Filter df by matching targets for multiple columns.

    Args:
        df (pd.DataFrame): dataframe
        filter_values (None or dict): Dictionary of the form:
                `{<field>: <target_values_list>}`
            used to filter columns data.
    """
    import numpy as np
    if filter_values is None or not filter_values:
        return df
    return df[
        np.logical_and.reduce([
            df[column].isin(target_values)
            for column, target_values in filter_values.items()
        ])
    ]

용법:

df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': [1, 2, 3, 4]})

filter_df(df, {
    'a': [1, 2, 3],
    'b': [1, 2, 4]
})


답변