2015-06-26 30 views
6

Tôi đang cố gắng tìm ra cách áp dụng hàm lambda cho nhiều khung dữ liệu cùng một lúc, mà không cần hợp nhất các khung dữ liệu với nhau. Tôi đang làm việc với các tập dữ liệu lớn (> 60MM hồ sơ) và tôi cần phải cẩn thận hơn với quản lý bộ nhớ.Pandas: Áp dụng Lambda vào nhiều khung dữ liệu

Mong muốn của tôi là có cách áp dụng lambda cho các khung dữ liệu bên dưới để tôi có thể tránh chi phí ghép chúng lại với nhau trước, sau đó thả dataframe trung gian đó khỏi bộ nhớ trước khi chuyển sang bước tiếp theo quá trình.

Tôi có kinh nghiệm né tránh vấn đề bộ nhớ bằng cách sử dụng các khung dữ liệu dựa trên HDF5, nhưng tôi muốn thử khám phá điều gì đó khác trước tiên.

Tôi đã cung cấp một vấn đề đồ chơi để giúp chứng minh những gì tôi đang nói đến.

import numpy as np 
import pandas as pd 

# Here's an arbitrary function to use with lambda 
def someFunction(input1, input2, input3, input4): 
    theSum = input1 + input2 
    theAverage = (input1 + input2 + input3 + input4)/4 
    theProduct = input2 * input3 * input4 
    return pd.Series({'Sum' : theSum, 'Average' : theAverage, 'Product' : theProduct}) 

# Cook up some dummy dataframes 
df1 = pd.DataFrame(np.random.randn(6,2),columns=list('AB')) 
df2 = pd.DataFrame(np.random.randn(6,1),columns=list('C')) 
df3 = pd.DataFrame(np.random.randn(6,1),columns=list('D')) 

# Currently, I merge the dataframes together and then apply the lambda function 
dfConsolodated = pd.concat([df1, df2, df3], axis=1) 

# This works just fine, but merging the dataframes seems like an extra step 
dfResults = dfConsolodated.apply(lambda x: someFunction(x['A'], x['B'], x['C'], x['D']), axis = 1) 

# I want to avoid the concat completely in order to be more efficient with memory. I am hoping for something like this: 
# I am COMPLETELY making this syntax up for conceptual purposes, my apologies. 
dfResultsWithoutConcat = [df1, df2, df3].apply(lambda x: someFunction(df1['A'], df1['B'], df2['C'], df3['D']), axis = 1) 
+1

rất khó để hiểu nếu điều này là giá trị trả lời như vấn đề hiện tại của bạn có thể được giải quyết mà không áp dụng lambda và concatenating, bạn có thể giải thích những gì bạn đang thực sự ** ** cố gắng để đạt – EdChum

+0

Trong mã ví dụ của tôi, tôi bắt đầu với ba dataframes [df1, df2, df3]. Sau đó, tôi cần phải tạo một khung dữ liệu trung gian được gọi là dfConsolodated, chỉ đơn giản là ba khung dữ liệu bên dưới được kết hợp với nhau. Điều này là tốt với vấn đề đồ chơi, nhưng khi tôi đang hoạt động trên> 60 triệu bản ghi trên mỗi khung dữ liệu, tôi có thể làm cho bộ nhớ nhanh chóng tăng lên nhanh chóng với bảng dfConsolodated. Mục tiêu thực sự, là bảo tồn tài nguyên hệ thống bằng cách tránh concat ở nơi đầu tiên. – jtrowbridge

+0

Tất cả các Khung dữ liệu có cùng hình dạng không? – Alexander

Trả lời

1

Một lựa chọn sẽ được tạo ra một cách rõ ràng quy tụ mong muốn:

theSum = df1.A + df1.B 
theAverage = (df1.A + df1.B + df2.C + df3.D)/4. 
theProduct = df1.B * df2.C * df3.D 
theResult = pd.concat([theSum, theAverage, theProduct]) 
theResult.columns = ['Sum', 'Average', 'Product'] 

Một khả năng khác là sử dụng query, nhưng điều này thực sự phụ thuộc vào trường hợp sử dụng của bạn và làm thế nào bạn có ý định để tổng hợp dữ liệu của bạn. Dưới đây là ví dụ về các tài liệu có thể áp dụng cho bạn.

map(lambda frame: frame.query(expr), [df, df2]) 
+0

Điều này làm việc trong ví dụ bởi vì toán trong ví dụ của tôi là đơn giản. Trong thực tế, tôi đang sử dụng một mô hình thống kê phức tạp hơn sử dụng một số tích hợp số. Tôi không nghĩ rằng tôi có thể thoát ra với một cách rõ ràng tạo ra các tập hợp. Do sự phức tạp của mô hình, tôi nghĩ rằng tôi đang mắc kẹt với việc truyền dữ liệu vào các đối số hàm. – jtrowbridge

+0

Tôi nên đề cập rằng ý tưởng truy vấn đáng xem xét, cảm ơn ý tưởng tôi sẽ cho nó một xoáy. Quay lại câu hỏi ban đầu của tôi, thậm chí có thể sử dụng lambda trên nhiều khung hình, cá nhân, dữ liệu không? – jtrowbridge

+0

Tôi nhận thấy bạn là một anh chàng tài chính. Tôi đang thực sự tạo một khung dữ liệu lớn bao gồm một chuỗi thời gian các vị trí tùy chọn hàng ngày và tôi định giá chúng thông qua mô hình bảng đen châu Âu để có được giá và tất cả những người Hy Lạp điển hình. Sau đó tôi tính toán phân bổ P & L hàng ngày trên người Hy Lạp để có được chuỗi thời gian hàng ngày của P & L được quy cho tất cả các nhạy cảm có liên quan. Tôi không thể chạy BS bằng cách tạo một cách rõ ràng các tập hợp như bạn đã đề cập trước đây. – jtrowbridge

0

Tôi biết câu hỏi này khá cũ, nhưng đây là cách tôi đã nghĩ ra. Nó không đẹp, nhưng nó hoạt động.

Ý tưởng cơ bản là truy vấn khung dữ liệu thứ hai bên trong hàm được áp dụng. Bằng cách sử dụng tên của chuỗi đã qua, bạn có thể nhận dạng cột/chỉ mục và sử dụng nó để truy lục giá trị cần thiết từ (các) khung dữ liệu khác.

def func(x, other): 
    other_value = other.loc[x.name] 
    return your_actual_method(x, other_value) 

result = df1.apply(lambda x: func(x, df2)) 
Các vấn đề liên quan