2013-08-14 26 views
6

Giả sử tôi có một số pandas.DataFrame được gọi là df. Các cột của df đại diện cho các cá nhân khác nhau và trục chỉ số đại diện cho thời gian, vì vậy mục (i, j) là quan sát của cá nhân j trong khoảng thời gian i và chúng ta có thể giả định tất cả dữ liệu là float có thể với giá trị NaN.Cách nhanh để xem số lượng quan sát phổ biến cho các mục nhập ma trận tương quan Python Pandas

Trong trường hợp của tôi, tôi có khoảng 14.000 cột và vài trăm hàng.

pandas.corr sẽ trả lại ma trận tương quan 14.000 x 14.000 và hiệu suất thời gian của nó là tốt cho ứng dụng của tôi. Nhưng tôi cũng muốn biết, đối với mỗi cặp cá nhân (j_1, j_2), có bao nhiêu quan sát không null đi vào tính toán tương quan, vì vậy tôi có thể cô lập các ô tương quan bị phủ sóng dữ liệu kém.

Điều tốt nhất tôi đã có thể đưa ra như sau:

not_null_locations = pandas.notnull(df).values.astype(int) 
common_obs = pandas.DataFrame(not_null_locations.T.dot(not_null_locations), 
           columns=df.columns, index=df.columns) 

Các bộ nhớ và tốc độ này bắt đầu có một chút vấn đề.

Có cách nào nhanh hơn để nhận các quan sát chung với pandas không?

+2

bạn phần nào có thể giải quyết điều này bằng cách đi qua '' min_periods'' để corr (ví dụ của nó một cắt, nơi bạn có yêu cầu số lượng tối thiểu của các quan sát; không trực tiếp trả lời nhưng có thể cung cấp cho bạn một 'đủ tốt' trả lời – Jeff

+0

Đó là một gợi ý tuyệt vời, nhưng tôi đang làm việc trong một hệ thống sản xuất đòi hỏi phiên bản Pandas 0.8.0, và có vẻ như 'min_periods' đã được thêm vào trong một phiên bản mới hơn. Tôi không thể làm gì với phiên bản cũ, tôi sợ hãi – ely

+0

bạn có thể * thêm * nó trong mã (và biên dịch lại) nếu trên linux (nơi khá dễ dàng) ..... nó chỉ là một thay đổi dòng đôi (tất nhiên 'sản xuất' có thể ngăn cản điều này ....) – Jeff

Trả lời

3

Bạn có thể thực hiện việc này, nhưng sẽ cần phải tạo mã hóa (nếu không chậm hơn nhiều); Tuy nhiên bộ nhớ dấu chân nên được tốt hơn (điều này cho biết số quan sát nan, bạn mang đến cho số quan sát hợp lệ, nhưng dễ dàng chuyển đổi)

l = len(df.columns) 
results = np.zeros((l,l)) 
mask = pd.isnull(df) 
for i, ac in enumerate(df): 
    for j, bc in enumerate(df): 
      results[j,i] = (mask[i] & mask[j]).sum() 
results = DataFrame(results,index=df.columns,columns=df.columns) 
3

Bạn thực sự có thể làm cho @ câu trả lời của Jeff nhanh hơn một chút bởi chỉ lặp lại lên đến (nhưng không bao gồm) i + 1 trong vòng lặp lồng nhau và vì tương quan là đối xứng, bạn có thể gán giá trị cùng một lúc. Bạn cũng có thể di chuyển truy cập mask[i] bên ngoài vòng lặp lồng nhau, đó là một tối ưu hóa nhỏ nhưng có thể mang lại một số lợi ích hiệu suất cho các khung hình rất lớn.

l = len(df.columns) 
results = np.zeros((l,l)) 
mask = pd.isnull(df) 
for i in range(l): 
    maski = mask[i] 
    for j in range(i + 1): 
      results[i,j] = results[j,i] = (maski & mask[j]).sum() 
results = DataFrame(results,index=df.columns,columns=df.columns) 
Các vấn đề liên quan