2015-07-09 17 views
7

tôi relativly mới để Python và tôi có một chút vấn đề với một tập hợp dữ liệu. Tập dữ liệu có 400.000 hàng và 300 biến. Tôi phải lấy các biến giả cho một biến phân loại với 3000 mục khác nhau. Cuối cùng tôi muốn kết thúc với một bộ dữ liệu với 3300 biến hoặc các tính năng để tôi có thể đào tạo mô hình RandomForest.get_dummies lỗi bộ nhớ python

Dưới đây là những gì tôi đã cố gắng để làm:

df = pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_')], axis=1) 

Khi tôi làm điều đó, tôi sẽ luôn luôn nhận được một lỗi bộ nhớ. Có giới hạn về số biến tôi có thể có không?

Nếu tôi làm điều đó chỉ với 1000 hàng đầu tiên (có 374 danh mục khác nhau), nó chỉ hoạt động vây.

Có ai có giải pháp cho vấn đề của tôi không?

Máy tôi đang sử dụng là Intel I7 với RAM 8 GB.

Cảm ơn bạn

+0

Python 32 bit hoặc 64 bit? Giới hạn là kích thước heap của Python, đó là một vùng bộ nhớ ảo, không phải là RAM. Các phiên bản khác nhau và các triển khai khác nhau trên các hệ điều hành khác nhau đều có những hạn chế khác nhau.Rõ ràng bạn đã nhấn một. Bạn có phải lưu trữ tất cả dữ liệu đó trong bộ nhớ ảo cùng một lúc không? – cdarke

+0

Tôi đang sử dụng Python 64 bit. Điều gì sẽ là giải pháp cho điều đó? Rằng tôi chia bộ dữ liệu thành nhiều phần và thực hiện thao tác trên các phần khác nhau? – Duesentrieb

+0

OK, tôi sẽ đề nghị rằng nếu bạn đang ở trên 32-bit. Trong trường hợp đó, bạn cần phải xem lại thiết kế của bạn. – cdarke

Trả lời

18

update: Bắt đầu với phiên bản 0.19.0, get_dummies trả về một số nguyên 8bit chứ không phải 64bit float, mà sẽ khắc phục vấn đề này trong nhiều trường hợp. Xem: get_dummies -- pandas 0.19.0

Dưới đây là một vài khả năng để thử. Cả hai sẽ làm giảm dấu chân bộ nhớ của khung dữ liệu một cách đáng kể nhưng bạn vẫn có thể gặp phải vấn đề về bộ nhớ sau này. Thật khó dự đoán, bạn sẽ phải thử.

(lưu ý rằng tôi đang đơn giản hóa đầu ra của info() bên dưới)

df = pd.DataFrame({ 'itemID': np.random.randint(1,4,100) }) 

pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_')], axis=1).info() 

itemID  100 non-null int32 
itemID__1 100 non-null float64 
itemID__2 100 non-null float64 
itemID__3 100 non-null float64 

memory usage: 3.5 KB 

Đây là cơ sở của chúng tôi. Mỗi cột giả chiếm 800 byte vì dữ liệu mẫu có 100 hàng và get_dummies xuất hiện mặc định là float64 (8 byte). Điều này có vẻ như một cách không hiệu quả không cần thiết để lưu trữ núm vú giả như bạn có thể sử dụng ít nhất là một chút để làm điều đó, nhưng có thể có một số lý do cho điều mà tôi không biết.

Vì vậy, nỗ lực đầu tiên, chỉ cần thay đổi sang một byte số nguyên (điều này dường như không có một lựa chọn cho get_dummies vì vậy nó phải được thực hiện dưới dạng chuyển đổi với astype(np.int8).

pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_').astype(np.int8)], 
           axis=1).info() 

itemID  100 non-null int32 
itemID__1 100 non-null int8 
itemID__2 100 non-null int8 
itemID__3 100 non-null int8 

memory usage: 1.5 KB 

Mỗi cột giả hiện nay chiếm 1/8 bộ nhớ như trước đây.

Ngoài ra, bạn có thể sử dụng tùy chọn sparseget_dummies.

pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_',sparse=True)], 
           axis=1).info() 

itemID  100 non-null int32 
itemID__1 100 non-null float64 
itemID__2 100 non-null float64 
itemID__3 100 non-null float64 

memory usage: 2.0 KB 

Tiết kiệm tương đối hợp lý. Đầu ra info() phần nào ẩn cách tiết kiệm đang xảy ra, nhưng bạn có thể xem giá trị sử dụng bộ nhớ để xem tổng tiết kiệm.

Thật khó để nói điều nào trong số này sẽ hoạt động tốt hơn trong thực tế (nếu một trong hai là giải pháp thiết thực), vì vậy bạn chỉ cần thử mỗi lần thử. Về lý thuyết bạn thậm chí có thể kết hợp hai phương pháp tiếp cận, nhưng tôi sẽ không cố gắng trừ khi nó chỉ ra mỗi cách tiếp cận hoạt động trên riêng của nó.

+0

Cảm ơn bạn rất nhiều. Tôi đã thay đổi kiểu dữ liệu thành số nguyên và nó hoạt động! – Duesentrieb