2015-11-09 35 views
5

Tôi đang truy cập vào một khung dữ liệu Pandas rất lớn dưới dạng biến toàn cục. Biến này được truy cập song song qua joblib.Large Pandas Dataframe xử lý song song

Ví dụ:

df = db.query("select id, a_lot_of_data from table") 

def process(id): 
    temp_df = df.loc[id] 
    temp_df.apply(another_function) 

Parallel(n_jobs=8)(delayed(process)(id) for id in df['id'].to_list()) 

Truy cập df gốc theo cách này có vẻ như sao chép dữ liệu qua các quy trình. Điều này là bất ngờ vì df gốc không bị thay đổi trong bất kỳ quy trình con nào? (hoặc là nó?)

Trả lời

7

Toàn bộ DataFrame cần phải được chọn và bỏ chọn cho mỗi quá trình được tạo bởi joblib. Trong thực tế, điều này là rất chậm và cũng đòi hỏi nhiều lần bộ nhớ của mỗi.

Một giải pháp là lưu trữ dữ liệu của bạn ở định dạng HDF (df.to_hdf) sử dụng định dạng bảng. Sau đó, bạn có thể sử dụng select để chọn tập hợp con dữ liệu để xử lý tiếp. Trong thực tế, điều này sẽ quá chậm để sử dụng tương tác. Nó cũng rất phức tạp, và công nhân của bạn sẽ cần phải lưu trữ công việc của họ để nó có thể được củng cố trong bước cuối cùng.

Cách khác là khám phá numba.vectorize với target='parallel'. Điều này sẽ yêu cầu sử dụng các mảng NumPy không phải là các đối tượng Pandas, vì vậy nó cũng có một số chi phí phức tạp.

Về lâu dài, dask được hy vọng mang lại sự thực hiện song song với gấu trúc, nhưng đây không phải là điều mong đợi sớm.

+1

Tôi đã giả định từ http://stackoverflow.com/questions/10721915/shared-memory-objects-in-python-multiprocessing rằng các quy trình con sẽ không nhận được bản sao đầy đủ trừ khi đối tượng gốc bị thay đổi. Joblib có bị ngắt với ngữ nghĩa copy-on-write không? – autodidacticon

+1

Chỉ một số ít loại có thể được truyền qua bộ nhớ dùng chung. Các đối tượng gấu trúc không có trong danh sách này. joblib tự động xử lý việc chia sẻ bộ nhớ cho các mảng numpy tùy thuộc vào kích thước của mảng bằng cách sử dụng đối số từ khóa 'max_nbytes' khi gọi' Parallel'. Xem [trang web của joblib] (https://github.com/joblib/joblib/blob/master/doc/parallel_numpy.rst). Cũng thấy [câu trả lời này] (http://stackoverflow.com/a/22487898/2551705). Bạn có thể sử dụng các mảng NumPy thay cho Pandas và bạn có thể thấy tăng tốc. –

1

Xử lý đa nhân Python thường được thực hiện bằng các quy trình riêng biệt, như bạn đã lưu ý, có nghĩa là các quá trình không chia sẻ bộ nhớ. Có một cách giải quyết tiềm ẩn nếu bạn có thể làm việc với np.memmap như đã đề cập ở trên một chút so với tài liệu joblib, mặc dù bán phá giá vào đĩa rõ ràng sẽ thêm một số chi phí của riêng nó: https://pythonhosted.org/joblib/parallel.html#working-with-numerical-data-in-shared-memory-memmaping

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