2017-12-14 2 views
1

A, B, C, D, E, F, G, H 열이있는 팬더 데이터 프레임 df이 있고 "행"을 받아들이고 행이 특정 조건을 충족하는지에 따라 true 또는 false를 반환하는 functn 함수를 사용하여 데이터 프레임을 필터링하려고한다고 가정 해 보겠습니다. 조건 (함수가 H을 제외한 모든 열을 사용한다고 가정하십시오). 오랫동안 추악한 람다없이이 데이터 프레임을 효율적으로 필터링하는 방법이 있습니까?필터를 사용하여 팬더 데이터 프레임

df = df[df.apply(functn, axis=1)] 

을하지만,이 방법은도 15K 라인과 프레임, 아주 느린 것 같다 : 내가 가지고있는이 솔루션은 지금까지 다음과 같습니다. 람다 또는 쿼리 대신 사용자 정의 파이썬 함수를 사용하여 판다 데이터 프레임을 필터링하는 깨끗하고 효율적인 방법이 있습니까?

참고 : 이전에 일반 Python 2D 배열을 사용하여이 기능을 구현했으며 판다를 사용하는 것보다 훨씬 빠릅니다. 특정 기능을 오용하고 있거나 필터링 프로세스를 더 빨리 수행 할 수있는 방법을 모르고 있습니까?

편집 :

데이터는 다음과 같이 대략 구성되어있다 :

#  A  B  C  D  E  F  G  H  
[ 
    [string1, string2, int1, int2, int3, int4, float1, float2], 
    ... 
] 

기능이 같은 작업을 수행합니다 비 팬더 구현은 기본적으로 dataframe을했다

def filter(row): 
    var1 = row.G <= 0.01 
    partial_a = (((row.D - row.C + 1)*1.0)/global_map[row.A]) 
    partial_b = (((row.F - row.E + 1)*1.0)/global_map[row.B]) 
    partial = partial_a >= 0.66 or partial_b >= 0.66 
    return var1 and partial 

하는 판다 형태가 아니라면 기본적으로 2 차원 배열이었고 각 요소를 반복하면서 함수를 적용했습니다 (인수는 "행"대신 목록이었습니다). true를 반환하면 새 요소를 다른 목록에 추가합니다.

+1

당신은 (A) 예를 들어, 데이터를 제공 할 수 있는지 당신을 도와 (b)에 fucntn', 및 (c)'의 세부 사항이 아닌 팬더 구현 쉬울 것이다 당신이 사용 했어. 즉, 병목 현상이 어디 있는지 알기가 어렵습니다. (벤치마킹 데이터도 좋을 것입니다.) –

+0

원본 게시물을 편집하여이를 반영합니다. 감사! – Swarage

+0

@andrew_reece 업데이트해야합니다! – Swarage

답변

3

IIUC, 기능이 필요하지 않습니다. 다음의 부울 색인을 사용하자 :

cond1 = df['G'] <= 0.01 
cond2 = (((df.D - df.C + 1)*1.0)/global_map[df.A]) >= 0.66 
cond3 = (((df.F - df.E + 1)*1.0)/global_map[df.B]) >= 0.66 

mask = cond1 & (cond2 | cond3) 

df[mask] 
+0

감사합니다. 후속 조치로서이 마스크를 일반화하여 다른 데이터 프레임에 적용 할 수있는 방법이 있습니까? 내가 언급 한 'df'를 참조하기 때문에 이것이 구체적이라고 생각합니다. – Swarage

+2

'global_map'이 dict 인 경우,'np.vectorize (global_map.get) (df.A)'와 같은 lookup을 vectorize 할 필요가 있습니다. –

+0

마스크를 생성하고 적용하기 위해 함수로 쓸 수 있어야합니다 루핑없이 데이터 프레임에 대한 마스크. –