정규식으로 팬더의 행을 필터링하는 방법


169

열 중 하나에서 정규 표현식을 사용하여 데이터 프레임을 깨끗하게 필터링하고 싶습니다.

고안된 예 :

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

그래도 인위적으로 정규식에 그룹을 넣을 수 있으며 깨끗한 방법이 아닌 것 같습니다. 더 좋은 방법이 있습니까?


5
정규식에 얽매이지 않으면 foo[foo.b.str.startswith("f")]작동합니다.
DSM

IMHO 나는 foo[foo.b.str.match('(f.*)').str.len() > 0]꽤 좋은 해결책 이라고 생각 합니다! 정규식의 다양한 기능을 제공하기 때문에 시작보다 더 사용자 정의 가능하고 유용합니다.
tumultous_rooster 1

3
약간 늦었지만 최신 버전의 팬더에서는 문제가 해결되었습니다. 이 선 foo[foo.b.str.match('f.*')]은 팬더 0.24.2에서 작동합니다.
Behzad Mehrtash

답변:


198

사용은 포함 대신 :

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

11
부울을 어떻게 뒤집을 수 있습니까? 그것을 발견 : stackoverflow.com/questions/15998188/…
dmeu

4
True를 가진 행만 가져올 수 있습니까?
충격파

2
@shockwave 다음을 사용해야합니다.df.loc[df.b.str.contains('^f'), :]
Rafa

1
@shockwave 또한 당신은 또한 사용할 수 있습니다df[df.b.str.contains('^f'), :]
David Jung

24

문자열 처리 기능이 이미 있습니다 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=False nan, null 등의 값이있는 경우 오류를 방지하는 것입니다.


나는 이것을 수정했고 그것은 나를 위해 일했다df[~df.CITY.str.contains('~.*', regex= True, na=False)]
Patty Jula

감사합니다! 이것은 훌륭한 솔루션입니다
Kedar Joshi

20

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

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

2
frame? 그리고 'C:\test\test.txt'? 다른 질문에 답변 한 것 같습니다.
tumultous_rooster 2016 년

프레임은 df입니다. 동일한 질문과 관련이 있지만 한 줄 코드에서 여러 열 ( 'filename'및 'file_path')을 필터링하는 방법에 대한 답변입니다.
lakshman senathirajah

12

약간 늦을 수도 있지만, 이제 Pandas에서 수행하기가 더 쉽습니다. as_indexer=True부울 결과를 얻기 위해 일치를 호출 할 수 있습니다 . 이것은 (차이와 함께 설명되어 있습니다 matchcontains) 여기 .


11

@ user3136169의 훌륭한 답변에 감사드립니다. 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)]

또한 정규식을 인수로 추가 할 수도 있습니다.

def regex_filter(val,myregex):
    ...

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

1
덕분에 임의의 술어로 열을 필터링하는 방법을 찾았습니다.
jman

9

정규 표현식을 확인하고 열에 적용하는 부울 함수를 작성하십시오.

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

1

str 슬라이스 사용

foo[foo.b.str[0]=='f']
Out[18]: 
   a    b
1  2  foo
2  3  fat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.