2013-08-10 42 views
6

Tôi có DataFrame sau đây mà tôi muốn áp dụng một số tính toán phạm vi ngày. Tôi muốn chọn các hàng trong khung ngày mà sự khác biệt ngày giữa các mẫu cho những người duy nhất (từ sample_date) nhỏ hơn 8 tuần và giữ cho hàng có ngày cũ nhất (ví dụ: mẫu đầu tiên).Áp dụng chức năng cho một dataframe MultiIndex với gấu trúc/python

Đây là tập dữ liệu mẫu. Tập dữ liệu thực tế có thể vượt quá 200.000 bản ghi.

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 

Người duy nhất là những người có cùng tên và dob. Ví dụ: John A, James, Mark A và Mark B là những người độc nhất. Tuy nhiên, Mark A có các giá trị id khác nhau.

Tôi thường sử dụng R cho quy trình và tạo danh sách các khung dữ liệu dựa trên tên/kết hợp dob và sắp xếp từng khung dữ liệu theo sample_date. Sau đó tôi sẽ sử dụng một danh sách áp dụng chức năng để xác định nếu sự khác biệt trong ngày giữa nắm tay và chỉ số cuối cùng trong mỗi dataframe để trở về lâu đời nhất nếu nó ít hơn 8 tuần kể từ ngày gần đây nhất. Phải mất mãi mãi.

Tôi sẽ hoan nghênh một vài gợi ý về cách tôi có thể thử điều này với python/gấu trúc. Tôi bắt đầu bằng cách tạo một MultiIndex với tên/dob/id. Cấu trúc trông giống như những gì tôi muốn. Những gì tôi cần làm là thử áp dụng một số hàm tôi sử dụng trong R để chọn ra các hàng tôi cần. Tôi đã thử chọn với df.xs() nhưng tôi không nhận được rất xa.

Dưới đây là từ điển dữ liệu có thể được tải dễ dàng vào gấu trúc (mặc dù với thứ tự cột khác nhau).

{ 'DOB': {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}, 'vị trí': {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'}, ' name ': {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: 'Đánh dấu 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 '},' sex ' : {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

Giả sử có sáu mẫu cho Mark A. Ba mẫu đầu tiên được phân tách bằng sáu tuần, sau đó có khoảng cách bốn tháng, và sau đó ba giây thứ hai cũng được phân tách bằng sáu tuần. Bạn muốn giữ những hàng nào? (IOW, tôi không chắc chắn về phạm vi "sự khác biệt ngày giữa các mẫu"). – DSM

+0

Điểm tốt @DSM. Nếu sự khác biệt ngày giữa mẫu cũ nhất tập hợp gần đây nhất cho Mark A là hơn 8 tuần, tôi muốn xử lý thiết bị Mark A khác như một bộ mẫu mới. IOW nếu ngày chênh lệch giữa hai mẫu> 8 tuần đối với mỗi mẫu được thiết lập độc lập. – John

Trả lời

6

tôi nghĩ rằng những gì bạn có thể tìm kiếm là

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) 

Tùy thuộc vào việc hay không bạn muốn giữ lại những người không có nhiều hơn 1 mẫu mà bạn có thể gọi delta.dropna(how='all') để loại bỏ chúng.

Lưu ý rằng tôi nghĩ rằng bạn sẽ cần numpy >= 1.7 cho việc so sánh timedelta64 để làm việc một cách chính xác, vì có một loạt toàn bộ vấn đề với timedelta64/datetime64 cho numpy < 1.7.

Các vấn đề liên quan