source

판다의 열을 regex로 필터링하는 방법

factcode 2022. 11. 25. 20:50
반응형

판다의 열을 regex로 필터링하는 방법

한 컬럼의 regex를 사용하여 데이터 프레임을 깔끔하게 필터링하고 싶습니다.

의도된 예:

In [210]: foo = pd.DataFrame({'a' : [1,2,3,4], 'b' : ['hi', 'foo', 'fat', 'cat']})
In [211]: foo
Out[211]: 
   a    b
0  1   hi
1  2  foo
2  3  fat
3  4  cat

다음 행으로 시작하는 행으로 필터링합니다.f정규식을 사용합니다.첫 번째 시작:

In [213]: foo.b.str.match('f.*')
Out[213]: 
0    []
1    ()
2    ()
3    []

별로 쓸모가 없군요.단, 부울 인덱스가 표시됩니다.

In [226]: foo.b.str.match('(f.*)').str.len() > 0
Out[226]: 
0    False
1     True
2     True
3    False
Name: b

그러면 다음과 같이 제한을 할 수 있습니다.

In [229]: foo[foo.b.str.match('(f.*)').str.len() > 0]
Out[229]: 
   a    b
1  2  foo
2  3  fat

그래서 인위적으로 그룹을 정규식에 넣게 된 거고, 어쩌면 깔끔한 방법이 아닌 것 같아요.더 좋은 방법이 있을까요?

대신 다음을 사용합니다.

In [10]: df.b.str.contains('^f')
Out[10]: 
0    False
1     True
2     True
3    False
Name: b, dtype: bool

문자열 처리 함수가 이미 있습니다.Series.str.startswith()한번 시도해 보세요.foo[foo.b.str.startswith('f')].

결과:

    a   b
1   2   foo
2   3   fat

당신이 기대하는 것 같아요.

또는 regex 옵션과 함께 contains를 사용할 수도 있습니다.예를 들어 다음과 같습니다.

foo[foo.b.str.contains('oo', regex= True, na=False)]

결과:

    a   b
1   2   foo

na=Falsenan, null 등의 값이 있는 경우의 에러를 방지하는 것입니다.

조금 늦을 수도 있지만, 이것은 이제 판다들에게 전화를 걸면 더 쉽게 할 수 있다.의사는 이 두 가지 차이점에 대해 설명합니다.match,fullmatch그리고.contains.

인덱스에 결과를 사용하려면 , 다음의 설정을 실시합니다.na=False인수(또는TrueNAN을 결과에 포함시키고 싶은 경우).

데이터 프레임을 사용한 다중 열 검색:

frame[frame.filename.str.match('*.'+MetaData+'.*') & frame.file_path.str.match('C:\test\test.txt')]

사용자 3136169훌륭한 답변을 바탕으로 NoneType 값을 제거하는 방법을 보여 줍니다.

def regex_filter(val):
    if val:
        mo = re.search(regex,val)
        if mo:
            return True
        else:
            return False
    else:
        return False

df_filtered = df[df['col'].apply(regex_filter)]

regex를 arg로 추가할 수도 있습니다.

def regex_filter(val,myregex):
    ...

df_filtered = df[df['col'].apply(regex_filter,regex=myregex)]

정규식을 검사하는 부울 함수를 작성하고 열에 apply를 사용합니다.

foo[foo['b'].apply(regex_function)]

Python의 내장된 lamda 식을 쓰는 기능을 사용하여 다음과 같이 임의의 regex 연산을 통해 필터링할 수 있습니다.

import re  

# with foo being our pd dataframe
foo[foo['b'].apply(lambda x: True if re.search('^f', x) else False)]

re.search를 사용하면 복잡한 regex 스타일의 쿼리로 필터링할 수 있습니다.이것은 제 생각에 더 강력한 것 같습니다.(과 같이)str.contains다소 제한적)

또, 주의할 점은 다음과 같습니다.작은 'f'로 시작하는 문자열입니다.regex를 사용하여f.*텍스트 내의 임의의 위치에서 f를 일치시킵니다.를 사용하여^기호는 내용 시작 부분에 기호가 표시되도록 명시적으로 명시합니다.그래서 사용하다^f아마 더 좋은 생각일 거예요:)

사용.str조각을 내라

foo[foo.b.str[0]=='f']
Out[18]: 
   a    b
1  2  foo
2  3  fat

는, 다음과 같이 조합해 사용할 수 있습니다.

foo.query('b.str.contains("^f").values')

또는 다음을 사용할 수도 있습니다.

foo.query('b.str.startswith("f").values')

그러나 첫 번째 대안은 여러 패턴을 검색할 수 있기 때문에 선호합니다.|교환입니다.

언급URL : https://stackoverflow.com/questions/15325182/how-to-filter-rows-in-pandas-by-regex

반응형