판다의 열을 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=False
nan, null 등의 값이 있는 경우의 에러를 방지하는 것입니다.
조금 늦을 수도 있지만, 이것은 이제 판다들에게 전화를 걸면 더 쉽게 할 수 있다.의사는 이 두 가지 차이점에 대해 설명합니다.match
,fullmatch
그리고.contains
.
인덱스에 결과를 사용하려면 , 다음의 설정을 실시합니다.na=False
인수(또는True
NAN을 결과에 포함시키고 싶은 경우).
데이터 프레임을 사용한 다중 열 검색:
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
'source' 카테고리의 다른 글
MySQL 데이터베이스 테이블의 최대 레코드 수 (0) | 2022.11.25 |
---|---|
MAMP에 PHP 버전을 추가하는 방법 (0) | 2022.11.25 |
Java에서의 HTTP POST 요구 전송 (0) | 2022.11.25 |
FOUND_ROWS가 있는 SQL_CALC_FOUND_ROWS는 항상 1을 반환합니다. (0) | 2022.11.25 |
Test Containers Framework가 도커 deamon에 연결할 수 없습니다. (0) | 2022.11.25 |