2017-11-21 1 views
2

팬더에서 I 정기적판다 한 라이너

df = df.groupby('A').filter(lambda x: len(x) >= THRESHOLD) 

df 가정 발생 횟수에 의해 dataframe를 필터링 다음 다른 열 'B'을 가지고 사용 특정 열 nunique 카운트하여 행을 필터링하고 I은 필터링 할 dataframe 해당 컬럼에 고유 한 값의 수에 의해이 시간, 나는

df = df.groupby('A').filter(lambda x: len(np.unique(x['B'])) >= THRESHOLD2) 

하지만 그건 작동하지 않는 것 같은 것이, 무엇을 올바른 방법이 될 것이라고 기대?

답변

4

nunique와 함께 좋은 작업을해야합니다

df = pd.DataFrame({'B':list('abccee'), 
        'E':[5,3,6,9,2,4], 
        'A':list('aabbcc')}) 

print (df) 
    A B E 
0 a a 5 
1 a b 3 
2 b c 6 
3 b c 9 
4 c e 2 
5 c e 4 

THRESHOLD2 = 2 
df1 = df.groupby('A').filter(lambda x: x['B'].nunique() >= THRESHOLD2) 
print (df1) 
    A B E 
0 a a 5 
1 a b 3 

그러나

경우 빠른 솔루션을 사용 transform 및 필터 boolean indexing에 의해 필요

df2 = df[df.groupby('A')['B'].transform('nunique') >= THRESHOLD2] 
print (df2) 
    A B E 
0 a a 5 
1 a b 3 

타이밍 :

np.random.seed(123) 
N = 1000000 
L = list('abcde') 
df = pd.DataFrame({'B': np.random.choice(L, N, p=(0.75,0.0001,0.0005,0.0005,0.2489)), 
        'A':np.random.randint(10000,size=N)}) 
df = df.sort_values(['A','B']).reset_index(drop=True) 
print (df) 

THRESHOLD2 = 3 

In [403]: %timeit df.groupby('A').filter(lambda x: x['B'].nunique() >= THRESHOLD2) 
1 loop, best of 3: 3.05 s per loop 

In [404]: %timeit df[df.groupby('A')['B'].transform('nunique')>= THRESHOLD2] 
1 loop, best of 3: 558 ms per loop 

주의 사항

결과는 그룹 수에 따라 성능을 처리하지 못하므로 일부 솔루션의 타이밍에 많은 영향을 미칩니다.

+1

그 것이었다 'nunique'는 정말로 그 것이다. – Dark

+0

나는 매우 가까웠다./ – bluesummers

+0

@bluesummers 대답은 당신의 타이틀에 있었다 : – miradulo