2013-08-10 24 views
6

Mam następujące DataFrame, które chcę zastosować niektóre obliczenia zakres dat. Chcę wybrać wiersze w ramce daty, w których różnica między datami dla próbek dla unikalnych osób (z sample_date) jest mniejsza niż 8 tygodni i zachować wiersz z najstarszą datą (tj. Pierwszą próbką).Zastosuj funkcję do ramki danych MultiIndex z pand/python

Oto przykładowy zestaw danych. Rzeczywisty zbiór danych może przekroczyć 200 000 rekordów.

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 

Osobami niepowtarzalnymi są osoby o tym samym nazwisku i nazwisku. Na przykład John A, James, Mark A i Mark B są wyjątkowymi osobami. Mark A ma jednak różne wartości id.

Zwykle używam R dla procedury i generuję listę ramek danych na podstawie kombinacji nazwa/dob i sortuję każdą ramkę danych według próbki_data. Następnie użyłbym funkcji stosującej listę, aby określić, czy różnica między datą a ostatnim indeksem w każdej ramce danych zwróciła najstarszą, jeśli była mniejsza niż 8 tygodni od ostatniej daty. To trwa wieczność.

Chciałbym powitać kilka wskazówek, w jaki sposób mogę spróbować to z python/pandy. Zacząłem od utworzenia MultiIndexu o nazwie/dob/id. Struktura wygląda tak, jak chcę. To, co muszę zrobić, to spróbować zastosować niektóre funkcje, których używam w R, aby wybrać potrzebne wiersze. Próbowałem wybrać z df.xs(), ale nie jestem bardzo daleko.

Tutaj znajduje się słownik danych, które można łatwo wczytać do pandy (aczkolwiek z inną kolejnością kolumn).

{ 'ur': {0: '12/07/1969' , 1: '10/01/1964' , 2: '30/08/1958' , 3: '30/08/1958 ', 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/12/1984 ', 14: ' 9/12/1984 '},' id ': {0: 12345, 1: 54321, 2: 87878, 3: 45454,
4: 33322, 5: 12345, 6: 33322, 7: 65655, 8: 65459, 9: 41211, 10: 12345, 11: 56465, 12: 45456, 13: 55544, 14: 55544}, 'labno': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10, 10: 11, 11: 12, 12: 13, 13: 14, 14 : 15}, "lokalizacja": {0: "A", 1: "B", 2: "A", 3: "B", 4: "C", 5: "A", 6: "A", 7 : "B", 8: "A", 9: "C", 10: "A", 11: "C", 12: "C", 13: "A", 14: "A"}, " imię ": {0:" John A ", 1:" John B ", 2: " James ", 3:" James ", 4:" Peter ", 5:" John A ", 6:" Peter ", 7: "Jack", 8: "Jill", 9: "Julie", 10: "Angela", 11: "Mark A",
12: "Mark A", 13: "Mark 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/09/2011 ', 10: '23/10/2006', 11: '4/04/2011', 12: '3/04/2011', 13: '13/09/2012 ", 14:" 1/01/2012 "}," seks " : {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

Załóżmy, że w przypadku Marka A. było sześć próbek. Pierwsze trzy są rozdzielone sześcioma tygodniami, a następnie przerwa wynosi cztery miesiące, a następnie trzy kolejne są również oddzielone sześcioma tygodniami. Które wiersze chcesz zachować? (IOW, nie jestem pewien co do zakresu "różnicy dat między próbkami".) – DSM

+0

Dobry punkt @DSM. Jeśli różnica między datą najstarszej próbki ostatniego zestawu dla Mark A wynosi więcej niż 8 tygodni, chciałbym traktować inny zestaw Mark A jako nowy zestaw próbek. IOW, jeśli różnica między dwiema próbkami> 8 tygodni traktuje każdą próbkę niezależnie. – John

Odpowiedz

6

myślę, co może być szukasz jest

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) 

w zależności od tego, czy chcesz zachować ludzi, którzy nie mają więcej niż 1 próbkę można nazwać delta.dropna(how='all') aby je usunąć.

Zauważ, że myślę, że trzeba numpy >= 1.7 dla porównania timedelta64 działać prawidłowo, gdyż istnieje całe mnóstwo problemów z timedelta64/datetime64 dla numpy < 1.7.

Powiązane problemy