2013-08-10 4 views
6

나는 다음과 같은 날짜 범위 계산을 적용하고자하는 DataFrame을 가지고 있습니다. 고유 한 사람 (샘플 _ 날짜)의 샘플 간 날짜 차이가 8 주 미만인 날짜 프레임에서 행을 선택하고 가장 오래된 날짜 (즉 첫 번째 샘플)로 행을 유지하려고합니다.pandas/python을 사용하여 MultiIndex 데이터 프레임에 함수 적용

다음은 예제 데이터 집합입니다. 실제 데이터 세트는 200,000 개의 레코드를 초과 할 수 있습니다.

labno name sex dob   id  location sample_date 
1  John A M 12/07/1969 12345 A   12/05/2112 
2  John B M 10/01/1964 54321 B   6/12/2010 
3  James M 30/08/1958 87878 A   30/04/2012 
4  James M 30/08/1958 45454 B   29/04/2012 
5  Peter M 12/05/1935 33322 C   15/07/2011 
6  John A M 12/07/1969 12345 A   14/05/2012 
7  Peter M 12/05/1935 33322 A   23/03/2011 
8  Jack M 5/12/1921 65655 B   15/08/2011 
9  Jill F 6/08/1986 65459 A   16/02/2012 
10  Julie F 4/03/1992 41211 C   15/09/2011 
11  Angela F 1/10/1977 12345 A   23/10/2006 
12  Mark A M 1/06/1955 56465 C   4/04/2011 
13  Mark A M 1/06/1955 45456 C   3/04/2011 
14  Mark B M 9/12/1984 55544 A   13/09/2012 
15  Mark B M 9/12/1984 55544 A   1/01/2012 

유일한 사람은 같은 이름과 생년월일을 가진 것들이다. 예를 들어 John A, James, Mark A 및 Mark B는 고유 한 사람입니다. 그러나 Mark A는 다른 id 값을가집니다.

나는 일반적으로 절차 R을 사용하여 이름/생년월일 조합에 따라 dataframes의 목록을 생성하고 sample_date하여 각 dataframe을 정렬 할 수 있습니다. 그런 다음 목록 적용 함수를 사용하여 가장 최근 날짜로부터 8 주 미만인 경우 각 데이터 프레임 내의 주먹과 마지막 인덱스 간의 날짜 차이가 가장 오래된 값을 반환하는지 결정합니다. 그것은 영원히 걸립니다.

나는 이것을 파이썬/팬더에서 어떻게 시도할지에 대한 몇 가지 지침을 환영합니다. 나는 name/dob/id를 가진 MultiIndex를 만드는 것으로 시작했다. 구조는 내가 원하는 것처럼 보입니다. 필요한 작업은 R에서 사용하는 함수 중 일부를 적용하여 필요한 행을 선택하는 것입니다. 나는 df.xs()로 선택 시도했지만 나는 아주 멀리지고 있지 않다. 여기

는 (다른 열 순서 불구) 팬더에 쉽게 장착 될 수있는 데이터의 사전이다.

{ "생년월일"{0 : '12// 1,969 07 '1 : '10/01/1964', 2 : '30/08/1958 ', 3 : '30/08/1915 ', 4 : '12/05/1935', 5 : '12/07/1969 ', 6 : '12/05/1935', 7 : '5/12/1921', 8 : '6/08/1986 ', 9 :'4/03/1992 ', 10 :'1/10/1977 ', 11 :'1/06/1955 ', 12 :'1/06/1955 ', 13 :'9/1천9백84분의 12 ', 14 : '1984년 9월 12일 '}'ID '{0 : 12,345, 1 : 54,321, 2 : 87,878, 3 : 45,454,
4 33322 5 12345 6 : 33322, 7 : 65,655, 8 : 65459, 9 : 41,211, 10 : 12345, 11 : 56,465, 12 : 45,456, 13 : 55,544, 14 : 55,544} 'labno'{0 : 1, 1 : 2, 2 : 3, 3 : 4, 5 : 5, 6 : 6 : 7,7 : 8, 8 : 9, 9 : 10, 10 : 11,11 : 12,12 : 13,13 : 14,14 : 15}, '위치'{0 'A', 1 'B', 2 'A', 3 'B', 4 'C', 5 'A', 6 'A', 7 : 'A', 14 : 'A'}, 'C', 12 : 'C', 13 : 'A', ' John ', 2 : 'James ', 3 :'James ', 4 :'Peter ', 5 :'John A ', 6 :'Peter ' 7 : '잭', 8 '질', 9 '줄리', 10 '안젤라', 11 '마크 A',
12 '마크 A', 13 '마크 B', 14 : 'Mark B'}, 'sample_date': {0 : '12/05/2112 ', 1 :'6/12/2010 ', 2 : '30/04/2012', 3 : '29/04/2012 ', 4 : '15/07/2011', 5 : '14/05/2012 ', 6 : '23/03/2011', 7 : '15/08/2011 ', 8 : '16/02/2012 ', 9 : '15// 2011 09', 10 : '23/2천6분의 10 ', 11'2011년 4월 4일 ', 12'2011년 3월 4일 ', 13 : '13/09/2012 ', 14 :'1/01/2012 '},'섹스 ' : 0 : 'M', 1 : 'M', 2 : 'M', 3 : 'M', 4 : 'M', 5 : 'M', 6 : 'M', 7 : 'M' 8 'F', 9 'F', 10
'F', 11 'M', 12 'M', 13 'M', 14 'M'}}

+0

은의 마크 A. 여섯 개 샘플 처음 세 후 사개월의 간격이, 그리고 다음 두 번째 세 가지도 육주에 의해 분리되어 6 주에 의해 분리가 있었다 가정 해 봅시다. 어떤 행을 보관하고 싶습니까? (IOW, "샘플 간의 날짜 차이"의 범위를 잘 모르겠습니다.) – DSM

+0

좋은 점 @DSM. 가장 최근에 Mark A에 대해 설정 한 가장 오래된 샘플 간의 날짜 차이가 8 주가 넘으면 다른 Mark A 세트를 새 샘플 세트로 취급하고 싶습니다. IOW는 두 샘플 간의 날짜 차이가 8 주 이상인 경우 각 샘플 세트를 독립적으로 처리합니다. – John

답변

6

나는 당신을 위해 무엇을 찾고있을 수있는 것은 당신이 당신이 그들을 제거하는 delta.dropna(how='all')를 호출 할 수있는 1 개 이상의 샘플이없는 사람들을 계속할지 여부에 따라

def differ(df): 
    delta = df.sample_date.diff().abs() # only care about magnitude 
    cond = delta.notnull() & (delta < np.timedelta64(8, 'W')) 
    return df[cond].max() 

delta = df.groupby(['dob', 'name']).apply(differ) 

생각합니다. 나는 timedelta64 비교가 제대로 작동하려면 numpy < 1.7에 대한 timedelta64/datetime64 문제의 전체 호스트가 당신이, numpy >= 1.7이 필요합니다 생각

참고.

관련 문제