[PYTHON] 팬더 데이터 프레임을 동적으로 필터링하기
PYTHON팬더 데이터 프레임을 동적으로 필터링하기
3 열에 대한 임계 값을 사용하여 팬더 데이터 프레임을 필터링하려고합니다.
import pandas as pd
df = pd.DataFrame({"A" : [6, 2, 10, -5, 3],
"B" : [2, 5, 3, 2, 6],
"C" : [-5, 2, 1, 8, 2]})
df = df.loc[(df.A > 0) & (df.B > 2) & (df.C > -1)].reset_index(drop = True)
df
A B C
0 2 5 2
1 10 3 1
2 3 6 2
그러나 필자는 사전에서 컬럼의 이름과 임계 값을 알려주는 함수 내에서이 작업을 수행하려고합니다. 여기에 내 첫 번째 시도는 괜찮습니다. 기본적으로 cond 변수 안에 필터를 넣고 실행합니다.
df = pd.DataFrame({"A" : [6, 2, 10, -5, 3],
"B" : [2, 5, 3, 2, 6],
"C" : [-5, 2, 1, 8, 2]})
limits_dic = {"A" : 0, "B" : 2, "C" : -1}
cond = "df = df.loc["
for key in limits_dic.keys():
cond += "(df." + key + " > " + str(limits_dic[key])+ ") & "
cond = cond[:-2] + "].reset_index(drop = True)"
exec(cond)
df
A B C
0 2 5 2
1 10 3 1
2 3 6 2
이제 마침내 나는 모든 것을 함수 안에 넣었고 작동을 멈췄다. (아마도 exec 함수는 함수 내부에서 사용되는 것을 좋아하지 않을 것이다!) :
df = pd.DataFrame({"A" : [6, 2, 10, -5, 3],
"B" : [2, 5, 3, 2, 6],
"C" : [-5, 2, 1, 8, 2]})
limits_dic = {"A" : 0, "B" : 2, "C" : -1}
def filtering(df, limits_dic):
cond = "df = df.loc["
for key in limits_dic.keys():
cond += "(df." + key + " > " + str(limits_dic[key])+ ") & "
cond = cond[:-2] + "].reset_index(drop = True)"
exec(cond)
return(df)
df = filtering(df, limits_dic)
df
A B C
0 6 2 -5
1 2 5 2
2 10 3 1
3 -5 2 8
4 3 6 2
exec 함수는 함수 내에서 사용될 때 다르게 작동하지만 문제를 해결하는 방법을 알지 못했습니다. 또한, 나는 두 가지 입력 주어진 필터링을 수행하는 함수를 정의하는 더 우아한 방법이 있어야합니다 궁금 해서요 : 1) df 및 2) limits_dic = { "A": 0, "B": 2, "C": - 1}. 이것에 대한 어떤 생각이라도 고맙게 생각합니다.
해결법
-
==============================
1.동적 쿼리를 작성하려는 경우 더 쉬운 방법이 있습니다. 목록 이해력과 str.join을 사용하는 방법은 다음과 같습니다.
동적 쿼리를 작성하려는 경우 더 쉬운 방법이 있습니다. 목록 이해력과 str.join을 사용하는 방법은 다음과 같습니다.
query = ' & '.join(['{}>{}'.format(k, v) for k, v in limits_dic.items()])
또는, 파이썬 3.6 +와 f - 문자열을 사용하여,
query = ' & '.join([f'{k}>{v}' for k, v in limits_dic.items()])
print(query) 'A>0 & C>-1 & B>2'
쿼리 문자열을 df.query에 전달합니다. 이는 다음과 같은 목적을위한 것입니다.
out = df.query(query) print(out) A B C 1 2 5 2 2 10 3 1 4 3 6 2
또한 부울 마스크를 얻고 자한다면 df.eval을 사용할 수 있습니다. 그리고 나서 인덱스는 그 후에 간단 해집니다 :
mask = df.eval(query) print(mask) 0 False 1 True 2 True 3 False 4 True dtype: bool out = df[mask] print(out) A B C 1 2 5 2 2 10 3 1 4 3 6 2
문자열 데이터를 사용하는 열을 쿼리해야하는 경우 위의 코드는 약간 수정해야합니다.
다음을 고려하십시오 (이 답변의 데이터).
df = pd.DataFrame({'gender':list('MMMFFF'), 'height':[4,5,4,5,5,4], 'age':[70,80,90,40,2,3]}) print (df) gender height age 0 M 4 70 1 M 5 80 2 M 4 90 3 F 5 40 4 F 5 2 5 F 4 3
그리고 열, 연산자 및 값의 목록 :
column = ['height', 'age', 'gender'] equal = ['>', '>', '=='] condition = [1.68, 20, 'F']
적절한 수정은 다음과 같습니다.
query = ' & '.join(f'{i} {j} {repr(k)}' for i, j, k in zip(column, equal, condition)) df.query(query) age gender height 3 40 F 5
from https://stackoverflow.com/questions/45925327/dynamically-filtering-a-pandas-dataframe by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 치료 및 응답 상태 코드 : 어떻게 검사 할 것인가? (0) | 2018.11.15 |
---|---|
[PYTHON] 파이썬 3 대 파이썬 2 맵 비헤이비어 (0) | 2018.11.15 |
[PYTHON] 판다 데이터 프레임에서 선택한 값이 목록에 있는지 확인하는 방법? (0) | 2018.11.15 |
[PYTHON] 타임 스탬프 열을 별도의 날짜 및 시간 열로 나누기 (0) | 2018.11.15 |
[PYTHON] Cygwin에서 Pip-3.2 설치하기 (0) | 2018.11.15 |