2016-07-25 11 views
8

Tôi có một tập tin csv ~ 50GB mà tôi phảiĐẩy nhanh tiến độ xử lý ánh sáng của ~ 50GB tập tin CSV

  • Đi vài tập con của các cột của CSV
  • Áp dụng một đặc điểm kỹ thuật chuỗi định dạng khác nhau để mỗi tập hợp con cột của CSV.
  • Xuất CSV mới cho từng tập hợp con với thông số định dạng của riêng nó.

Tôi đã chọn sử dụng Pandas và có cách tiếp cận chung để lặp qua các đoạn có kích thước nhỏ gọn (chỉ hơn nửa triệu dòng) để tạo DataFrame và thêm đoạn mã vào mỗi CSV đầu ra. Vì vậy, một cái gì đó như thế này:

_chunk_size = 630100 

column_mapping = { 
    'first_output_specification' : ['Scen', 'MS', 'Time', 'CCF2', 'ESW10'], 
    # ..... similar mappings for rest of output specifications 
} 
union_of_used_cols = ['Scen', 'MS', 'Time', 'CCF1', 'CCF2', 'VS', 'ESW 0.00397', 'ESW0.08', 
        'ESW0.25', 'ESW1', 'ESW 2', 'ESW3', 'ESW 5', 'ESW7', 'ESW 10', 'ESW12', 
        'ESW 15', 'ESW18', 'ESW 20', 'ESW22', 'ESW 25', 'ESW30', 'ESW 35', 
        'ESW40'] 

chnk_iter = pd.read_csv('my_big_csv.csv', header=0, index_col=False, 
         iterator=True, na_filter=False, usecols=union_of_used_cols) 

cnt = 0 
while cnt < 100: 
    chnk = chnk_iter.get_chunk(_chunk_size) 
    chnk.to_csv('first_output_specification', float_format='%.8f', 
       columns=column_mapping['first_output_specification'], 
       mode='a', 
       header=True, 
       index=False) 
    # ..... do the same thing for the rest of the output specifications 

    cnt += 1 

Vấn đề của tôi là rằng đây là thực sự chậm. Mỗi đoạn sẽ mất khoảng một phút để tạo thêm phụ lục cho các tệp CSV, và do đó tôi xem xét gần 2 giờ để hoàn thành nhiệm vụ.

Tôi đã cố gắng đặt một vài tối ưu hóa bằng cách chỉ sử dụng liên kết của các tập hợp con cột khi đọc trong CSV, cũng như thiết lập na_filter=False, nhưng vẫn không được chấp nhận. Tôi đã tự hỏi liệu có cách nào nhanh hơn để thực hiện việc xử lý ánh sáng của một tệp CSV bằng Python, hoặc bằng cách tối ưu hóa hoặc hiệu chỉnh theo cách tiếp cận của tôi hoặc có lẽ chỉ đơn giản là có một công cụ tốt hơn phù hợp cho loại công việc này sau đó Pandas ... với tôi (một người dùng Pandas thiếu kinh nghiệm) điều này có vẻ như nó nhanh như nó có thể nhận được với Pandas, nhưng tôi rất có thể bị nhầm lẫn.

+1

Có thể chuyển sang phương pháp tiếp cận cơ sở dữ liệu không? Đây là một tệp csv lớn! –

+1

@ Jylo Tôi thực sự mong rằng đó là trường hợp, nhưng không. –

+0

'Chunksize' có chứa số hàng bạn muốn có trong mỗi đoạn không? – albert

Trả lời

6

Tôi không nghĩ rằng bạn đang nhận được bất kỳ lợi thế nào từ khung dữ liệu của Panda, do đó, nó chỉ là thêm phí. Thay vào đó, bạn có thể sử dụng chính sách CSV module của python dễ sử dụng và được tối ưu hóa độc đáo trong C.

Cân nhắc đọc nhiều phần lớn hơn vào bộ nhớ (có thể là 10MB mỗi lần), sau đó ghi ra từng phần con cột được định dạng lại trước khi tiến đến đoạn tiếp theo. Bằng cách đó, tệp đầu vào chỉ được đọc và phân tích cú pháp một lần. Một cách tiếp cận khác bạn có thể thử là xử lý trước dữ liệu bằng lệnh Unix cut để trích xuất chỉ các cột có liên quan (để Python không phải tạo đối tượng và cấp phát bộ nhớ cho dữ liệu trong các cột không sử dụng): cut -d, -f1,3,5 somedata.csv

Cuối cùng, hãy thử chạy mã theo PyPy sao cho phần CPU bị ràng buộc trong tập lệnh của bạn được tối ưu hóa thông qua JIT truy tìm của chúng.

0

Tôi sẽ thử sử dụng mô-đun csv python và trình tạo.

Tôi đã tìm thấy các máy phát nhanh hơn nhiều so với các phương pháp khác để phân tích các nhật ký máy chủ lớn và như vậy.

import csv 

def reader(csv_filename): 
    with open(csv_filename, 'r') as f: 
     csvreader = csv.reader(f, delimiter=',', quotechar="'") 
     for line in csvreader: 
      yield line # line is a tuple 

def formatter(lines): 
    for line in lines: 
     # format line according to specs 
     yield formatted_line 

def write(lines, csv_filename): 
    with open(csv_filename, 'w') as f: 
     writer = csv.writer(f) 
     for line in lines: 
      writer.writerow(line) 

lines = reader('myfile.in.csv') 
formatted_lines = formatter(lines) 
write(formatted_lines, 'myfile.out.csv') 

Đây chỉ là để đọc một biến đổi đầu vào csv đơn thành csv đầu ra, nhưng bạn có thể viết trình định dạng và ghi để xuất nhiều tệp.

(Bây giờ tôi thấy câu hỏi này là một tháng tuổi - không chắc bạn đã giải quyết được vấn đề chưa - nếu không và nếu bạn muốn giải thích chi tiết hơn/ví dụ cho tôi biết.)

0

CPU nhanh hơn truy cập đĩa. Một mẹo là gzip tệp của bạn và đọc từ đó.

import gzip 

with gzip.open('input.gz','r') as fin: 
    for line in fin: 
     print('got line', line) 
Các vấn đề liên quan