2013-04-09 19 views
6

Tôi đang cố gắng chọn các hàng ngẫu nhiên từ bảng HDFStore khoảng 1 GB. Sử dụng RAM phát nổ khi tôi yêu cầu khoảng 50 hàng ngẫu nhiên.HDFStore: sử dụng table.select và RAM

Tôi đang sử dụng gấu trúc 0-11-dev, python 2.7, linux64.

Trong trường hợp đầu tiên này sử dụng RAM phù hợp với kích thước của chunk

with pd.get_store("train.h5",'r') as train: 
for chunk in train.select('train',chunksize=50): 
    pass 

Trong trường hợp thứ hai này, nó có vẻ như toàn bộ bảng được nạp vào RAM

r=random.choice(400000,size=40,replace=False) 
train.select('train',pd.Term("index",r)) 

Trong trường hợp cuối cùng này, Mức sử dụng RAM phù hợp với số lượng tương đương chunk

r=random.choice(400000,size=30,replace=False)  
train.select('train',pd.Term("index",r)) 

Tôi bối rối, tại sao di chuyển từ 30 đến 40 hàng ngẫu nhiên làm tăng mức sử dụng RAM đáng kể.

Note bảng đã được lập chỉ mục khi tạo ra như vậy mà index = range (nrows (bảng)) sử dụng đoạn mã sau:

def txtfile2hdfstore(infile, storefile, table_name, sep="\t", header=0, chunksize=50000): 
    max_len, dtypes0 = txtfile2dtypes(infile, sep, header, chunksize) 

    with pd.get_store(storefile,'w') as store: 
     for i, chunk in enumerate(pd.read_table(infile,header=header,sep=sep,chunksize=chunksize, dtype=dict(dtypes0))): 
      chunk.index= range(chunksize*(i), chunksize*(i+1))[:chunk.shape[0]] 
      store.append(table_name,chunk, min_itemsize={'values':max_len}) 

Cám ơn cái nhìn sâu sắc

EDIT để trả lời Zelazny7

Đây là tệp tôi đã sử dụng để viết Train.csv để đào tạo.h5. Tôi viết này sử dụng các yếu tố của mã Zelazny7 từ How to trouble-shoot HDFStore Exception: cannot find the correct atom type

import pandas as pd 
import numpy as np 
from sklearn.feature_extraction import DictVectorizer 


def object_max_len(x): 
    if x.dtype != 'object': 
     return 
    else: 
     return len(max(x.fillna(''), key=lambda x: len(str(x)))) 

def txtfile2dtypes(infile, sep="\t", header=0, chunksize=50000): 
    max_len = pd.read_table(infile,header=header, sep=sep,nrows=5).apply(object_max_len).max() 
    dtypes0 = pd.read_table(infile,header=header, sep=sep,nrows=5).dtypes 

    for chunk in pd.read_table(infile,header=header, sep=sep, chunksize=chunksize): 
     max_len = max((pd.DataFrame(chunk.apply(object_max_len)).max(),max_len)) 
     for i,k in enumerate(zip(dtypes0[:], chunk.dtypes)): 
      if (k[0] != k[1]) and (k[1] == 'object'): 
       dtypes0[i] = k[1] 
    #as of pandas-0.11 nan requires a float64 dtype 
    dtypes0.values[dtypes0 == np.int64] = np.dtype('float64') 
    return max_len, dtypes0 


def txtfile2hdfstore(infile, storefile, table_name, sep="\t", header=0, chunksize=50000): 
    max_len, dtypes0 = txtfile2dtypes(infile, sep, header, chunksize) 

    with pd.get_store(storefile,'w') as store: 
     for i, chunk in enumerate(pd.read_table(infile,header=header,sep=sep,chunksize=chunksize, dtype=dict(dtypes0))): 
      chunk.index= range(chunksize*(i), chunksize*(i+1))[:chunk.shape[0]] 
      store.append(table_name,chunk, min_itemsize={'values':max_len}) 

Ứng dụng như

txtfile2hdfstore('Train.csv','train.h5','train',sep=',') 
+0

Dường như bạn đang sử dụng HDFStore theo cách tương tự như cách tôi muốn sử dụng. Tôi không có thời gian để tạo mã trình bao bọc xử lý nhiều lưu trữ và truy xuất. Bạn có nhớ chia sẻ mã 'txtfile2dtypes' của mình không? Ngoài ra, dữ liệu của bạn có nhiều dữ liệu ký tự không? Tôi gặp sự cố khi lưu trữ tệp csv vào HDFStore với dữ liệu ký tự biến. Kích thước tệp sẽ tăng lên vì tôi phải đặt 'min_itemsize' thành giá trị lớn như vậy. Tôi háo hức chờ đợi sự bổ sung của một tùy chọn 'truncate'. – Zelazny7

+1

@ Zelazny7 Tôi đã cập nhật chuỗi bằng mã. Trên thực tế tôi đang sử dụng nó trên cùng một dữ liệu như của bạn, điều xe ủi đất của Kaggle.Tôi chưa dummyfied các biến phân loại để sử dụng 'sklearn' được nêu ra. – user17375

+1

Cảm ơn bạn rất nhiều! Nó trông giống như bóng bay kích thước tập tin của bạn trong cùng một cách tôi. Tệp ~ 120mb kết thúc trên 1 GB. Tôi tự hỏi nếu bạn hoặc Jeff sẽ biết nếu nó tốt hơn để lưu trữ chiều dài biến 'đối tượng' cột (thực sự chỉ là dây) bằng cách sử dụng' đặt' và giữ mỗi cột văn bản như là đối tượng HDFStore riêng của nó. – Zelazny7

Trả lời

6

Đây là một vấn đề được biết đến, xem tham khảo ở đây: https://github.com/pydata/pandas/pull/2755

Về cơ bản truy vấn được biến thành một numexpr biểu thức để đánh giá. Có vấn đề nơi tôi không thể chuyển nhiều điều kiện or tới numexpr (phụ thuộc vào tổng chiều dài của biểu thức được tạo).

Vì vậy, tôi chỉ giới hạn biểu thức mà chúng tôi chuyển đến numexpr. Nếu nó vượt quá một số lượng nhất định các điều kiện or, thì truy vấn được thực hiện dưới dạng bộ lọc chứ không phải là lựa chọn trong hạt nhân. Về cơ bản điều này có nghĩa là bảng được đọc và sau đó reindexed.

Đây là danh sách nâng cao của tôi: https://github.com/pydata/pandas/issues/2391 (17).

Để giải quyết sự cố, chỉ cần chia nhỏ các truy vấn của bạn thành nhiều câu hỏi và đồng thời kết quả. Nên nhanh hơn nhiều và sử dụng một lượng bộ nhớ không đổi

+1

Ok Cảm ơn. Tôi đã bỏ lỡ các vấn đề thread, tôi nên đã tìm kiếm các diễn đàn github đầu tiên. Nhân tiện, tôi chỉ nhận ra bạn là nhà phát triển hdfstore, vì vậy cảm ơn vì công việc tuyệt vời! – user17375

+0

Điều này khá mơ hồ và không may dễ dàng bỏ lỡ :) – Jeff

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