사용자가 Pandas DataFrame 또는 Series 객체에 여러 필터를 적용하려는 시나리오가 있습니다. 본질적으로 사용자가 런타임에 지정하는 여러 필터링 (비교 작업)을 효율적으로 연결하고 싶습니다.
필터는 추가되어야합니다 (일명 적용되는 각 필터는 결과가 좁아 야 함).
현재 사용하고 reindex()
있지만 매번 새 객체를 만들고 기본 데이터를 복사합니다 (문서를 올바르게 이해하면). 따라서 큰 Series 또는 DataFrame을 필터링 할 때 실제로 비효율적 일 수 있습니다.
내가 사용하는 것을 생각하고 apply()
, map()
또는 이와 유사한 일이 더 좋을 수 있습니다. 나는 여전히 팬더를 처음 접했지만 여전히 모든 것을 머리로 감싸려고합니다.
TL; DR
다음 형식의 사전을 가져 와서 각 작업을 주어진 Series 객체에 적용하고 '필터링 된'Series 객체를 반환하고 싶습니다.
relops = {'>=': [1], '<=': [1]}
긴 예
나는 현재 가지고있는 것의 예부터 시작하여 단일 Series 객체를 필터링합니다. 아래는 현재 사용중인 기능입니다.
def apply_relops(series, relops):
"""
Pass dictionary of relational operators to perform on given series object
"""
for op, vals in relops.iteritems():
op_func = ops[op]
for val in vals:
filtered = op_func(series, val)
series = series.reindex(series[filtered])
return series
사용자는 수행하려는 작업을 사전에 제공합니다.
>>> df = pandas.DataFrame({'col1': [0, 1, 2], 'col2': [10, 11, 12]})
>>> print df
>>> print df
col1 col2
0 0 10
1 1 11
2 2 12
>>> from operator import le, ge
>>> ops ={'>=': ge, '<=': le}
>>> apply_relops(df['col1'], {'>=': [1]})
col1
1 1
2 2
Name: col1
>>> apply_relops(df['col1'], relops = {'>=': [1], '<=': [1]})
col1
1 1
Name: col1
다시 말하지만, 위의 접근 방식의 '문제'는 중간 단계의 데이터를 불필요하게 복사 할 수 있다고 생각합니다.
또한 전달 된 사전에 연산자에 열을 포함하고 입력 사전을 기반으로 전체 DataFrame을 필터링 할 수 있도록 이것을 확장하고 싶습니다. 그러나 Series에 작동하는 모든 것을 DataFrame으로 쉽게 확장 할 수 있다고 가정합니다.
df.query
및 pd.eval
사용 사례에 대한 좋은 맞는 것처럼 보인다. pd.eval()
함수 계열, 기능 및 사용 사례 에 대한 자세한 내용은 pd.eval ()을 사용하여 팬더의 Dynamic Expression Evaluation을 방문하십시오 .