2017-01-04 1 views
2

같은 행 및 b :팬더 dataframe 필터링 예를 들어, 나는이 2 열 <code>a</code>와 <code>dataframe</code>이 GROUPBY

a = [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3] 
b = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1] 

내가 필터링 dataframe 기대하고 다음 groupby 기능을 사용하지 않고 [5,6,7,2,3,4,9,0,1]

을 (때문에 매우 큰 숫자 인 dataframe과 너무 오랜 시간이 걸리므로 사용할 수 없습니다.), 각 그룹의 마지막 3 개 항목을 어떻게 필터링합니까? a?

답변

2

접근 방법 # 1 : 여기 NumPy와 기반 접근 방식입니다 -

In [89]: a = np.array([1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3]) 
    ...: b = np.array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1]) 
    ...: 

In [90]: idx = np.append(np.nonzero(a[1:] > a[:-1])[0], a.size-1)[:,None] - [2,1,0] 

In [91]: b[idx].ravel() 
Out[91]: array([5, 6, 7, 2, 3, 4, 9, 0, 1]) 

전처리 단계로 각각 ab라는 dataframe의 열에서 그, df을 ceiving, 우리는과 같이, 배열과 같은 사람들을 추출해야 -

a = df.a.values 
b = df.b.values 

이 적어도 세 가지 요소를 가정 있습니다 그룹당. 그룹 당 3 개 이하의 경우는 다음 접근법을 읽으십시오.


접근 방법 # 2 : Scipy's binary dilationb 떨어져 요소를 선택하는 마스크를 만들 수있는 -

from scipy.ndimage.morphology import binary_dilation as imdilate 
def filter_lastN(a, b, N): 
    mask = np.zeros(a.size,dtype=bool) 
    mask[np.append(np.nonzero(a[1:] > a[:-1])[0],b.size-1)] = 1 
    return b[imdilate(mask,np.ones(N),origin=(N-1)//2)] 

샘플 실행 - 접근이 놀랍

In [198]: a 
Out[198]: array([1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3]) 

In [199]: b 
Out[199]: array([5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]) 

In [200]: filter_lastN(a,b,3) 
Out[200]: array([5, 6, 7, 2, 3, 4, 9, 0, 1]) 

In [201]: filter_lastN(a,b,5) 
Out[201]: array([5, 6, 7, 0, 1, 2, 3, 4, 7, 8, 9, 0, 1]) 
+0

너무 감사합니다 –

2

당신은 사용할 수 있습니다 다음 이전 인덱스 값을 얻을 groups의 마지막 행에 대한 첫 번째 선택 마지막 drop_duplicatesloc의 :

a = [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3] 
b = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1] 
df = pd.DataFrame({'a': a, 'b':b}) 
print (df) 
    a b 
0 1 1 
1 1 2 
2 1 3 
3 1 4 
4 1 5 
5 1 6 
6 1 7 
7 2 8 
8 2 9 
9 2 0 
10 2 1 
11 2 2 
12 2 3 
13 2 4 
14 3 5 
15 3 6 
16 3 7 
17 3 8 
18 3 9 
19 3 0 
20 3 1 
df1 = df.drop_duplicates('a',keep='last') 
print (df1) 
    a b 
6 1 7 
13 2 4 
20 3 1 

idx = sorted(df1.index.tolist() + (df1.index - 1).tolist() + (df1.index - 2).tolist()) 
print (idx) 
[4, 5, 6, 11, 12, 13, 18, 19, 20] 

print (df.loc[idx]) 
    a b 
4 1 5 
5 1 6 
6 1 7 
11 2 2 
12 2 3 
13 2 4 
18 3 9 
19 3 0 
20 3 1