Cập nhật DataFrame trong các quy trình python khác nhau trong thời gian thực


8

Vì vậy, giả sử Bạn có một quy trình Python đang thu thập dữ liệu thời gian thực với khoảng 500 hàng mỗi giây (điều này có thể được song song hóa để giảm xuống khoảng 50 ps) từ một hệ thống xếp hàng và nối nó vào DataFrame:

rq = MyRedisQueue(..)
df = pd.DataFrame()
while 1:
    recv = rq.get(block=True)
    # some converting
    df.append(recv, ignore_index = True)

Bây giờ câu hỏi là: Làm thế nào để sử dụng CPU dựa trên dữ liệu này? Vì vậy, tôi hoàn toàn nhận thức được những hạn chế của GIL , và nhìn vào đa xử Giám đốc namespace , ở đây quá , nhưng có vẻ như có một số nhược điểm liên quan đến độ trễ trên dataframe centerally giữ với . Trước khi đào sâu vào nó, tôi cũng đã thử pool.mapcái mà tôi nhận ra để áp dụng picklegiữa các quy trình, đó là cách làm chậm và có quá nhiều chi phí.

Vì vậy, sau tất cả những điều này cuối cùng tôi cũng tự hỏi, làm thế nào (nếu) một phần chèn 500 hàng mỗi giây (hoặc thậm chí 50 hàng mỗi giây) có thể được chuyển sang các quy trình khác nhau với thời gian CPU còn lại để áp dụng thống kê và chẩn đoán trên dữ liệu ở trẻ quy trình?

Có lẽ sẽ tốt hơn nếu thực hiện một ổ cắm tcp tùy chỉnh hoặc hệ thống xếp hàng giữa hai quy trình? Hoặc có một số triển khai trong pandashoặc các libaries khác để thực sự cho phép truy cập nhanh vào một khung dữ liệu lớn trong quy trình cha mẹ ? Tôi yêu gấu trúc!


Bạn có muốn chỉ thực hiện số liệu thống kê trên các khối từ 50 đến 500 hàng mới mỗi giây và liên tục nối nó vào một DF lớn không? DF lớn nên được lưu trữ hoặc bạn cần xử lý thời gian thực hơn để được thực hiện trên nó?
Ronald Luc

@RonaldLuc Nếu đó là một yêu cầu cần thiết, tôi sẽ giới hạn nó trong số liệu thống kê trên 50 đến 500 hàng mới, vâng. Tôi có thể giữ phương tiện và mức cao / mức thấp trong các biến phụ để theo dõi dữ liệu hiện có trong DataFrame lớn.
gies0r

Câu trả lời:


4

Trước khi chúng tôi bắt đầu, tôi nên nói rằng bạn đã không cho chúng tôi biết nhiều về mã của bạn nhưng hãy lưu ý rằng bạn chỉ chuyển 50/500 hàng mới đó mỗi giây cho quy trình con và cố gắng tạo DataFramequy trình lớn đó trong quy trình con.

Tôi đang làm việc trên một dự án giống hệt như bạn. Python có nhiều triển khai IPC như PipeQueuenhư bạn biết. Shared Memorygiải pháp có thể có vấn đề trong nhiều trường hợp, tài liệu chính thức của trăn AFAIK cảnh báo về việc sử dụng các ký ức được chia sẻ.

Theo kinh nghiệm của tôi, cách tốt nhất để chuyển đổi dữ liệu giữa chỉ hai quy trình là Pipe, vì vậy bạn có thể chọn DataFrame và gửi nó đến điểm cuối kết nối khác. Tôi thực sự khuyên bạn nên tránh TCPsocket ( AF_INET) trong trường hợp của bạn.

Gấu trúc DataFramekhông thể được chuyển đổi sang một quá trình khác mà không bị ngâm và tháo ra. vì vậy tôi cũng khuyên bạn nên chuyển dữ liệu thô dưới dạng các loại tích hợp như dictthay vì DataFrame. Điều này có thể làm cho dưa chua và bỏ chọn nhanh hơn và nó cũng có ít dấu chân bộ nhớ hơn.


Tôi đánh giá cao câu trả lời của bạn @AmirHmZ! Đặc biệt là liên kết đến điểm chuẩn là tốt (và các công cụ xung quanh nó, điều mà tôi chưa biết). Một giải pháp trong Shared Memorykhu vực - hy vọng có thể xử lý nhiều quy trình đọc từ các quy trình con, trong khi các quy trình chính đang nối với nó - có thể thực hiện từ những gì tôi thấy, nếu tôi hầu như không hạn chế quyền truy cập ghi vào quy trình cha.
gies0r

.. Nhưng tôi không biết, nếu shared memorytrong một số loại block statetrong khi viết cho nó? Điều đó có nghĩa là, các tiến trình con không được phép đọc DataFrame, trong khi tiến trình cha mẹ nối với nó (sẽ gần như luôn luôn).
gies0r

@ gies0r Xin lỗi vì sự không hoạt động của tôi, Nếu bạn định sử dụng Shared Memorygiải pháp, bạn nên đồng bộ hóa các quy trình con với quy trình của nhà cung cấp. Nó có thể được thực hiện bởi một multiprocessing.Lock: docs.python.org/3/library/...
AmirHmZ

0

Song song trong pandascó lẽ được xử lý tốt hơn bởi một động cơ khác hoàn toàn.

Hãy xem dự án Koalas của Databricks hoặc DataFrame của Dask .


Chà .. Đó là một số lượng rất lớn mã được xem xét và sửa chữa ... Các nhiệm vụ có vẻ như nó có sự thích nghi tốt, nhưng nó vẫn là một tấn công việc. Bạn có biết về một ví dụ, trong đó khoảng thời gian tải / cập nhật dữ liệu như thời gian được đề cập trong câu hỏi đã được triển khai / ghi lại không?
gies0r

Tôi đã sử dụng Dask để xử lý bộ dữ liệu 200 GB GB song song và dung lượng bộ nhớ nhỏ, nhưng nó không trực tuyến. Dask về cơ bản là nhiều datafram gấu trúc xếp chồng lên nhau.
Ronald Luc

@RonaldLuc bạn đã thực hiện loại hoạt động nào trên máy cục bộ của mình?
Datanovice

Tải từ sàn gỗ, các thao tác số theo hàng, tính toán định vị địa lý, một số thao tác trên "DataFrame địa phương" ( df.map_partitions) và sau đó groupbylập chỉ mục (quan trọng đối với hiệu suất trong Dask), lưu dưới dạng CSV.
Ronald Luc

0

Một giải pháp đơn giản sẽ là tách quá trình thành hai giai đoạn khác nhau. Sử dụng Asyncio để nhận dữ liệu theo cách không chặn và thực hiện các biến đổi của bạn trong đó. Giai đoạn thứ hai sẽ sử dụng Hàng đợi Asyncio để xây dựng Khung dữ liệu. Điều này giả sử rằng bạn không cần DataFrame có sẵn cho một quy trình khác trong khi bạn đang nhận dữ liệu từ Hàng đợi Redis.

Dưới đây là một ví dụ về xây dựng mô hình nhà sản xuất / người tiêu dùng với Asyncio

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.