Hướng dẫn how do you split a large file into smaller files in python? - làm thế nào để bạn chia một tệp lớn thành các tệp nhỏ hơn trong python?

Tôi gặp một số khó khăn khi cố gắng phân chia các tệp lớn (giả sử, khoảng 10GB). Ý tưởng cơ bản chỉ đơn giản là đọc các dòng và nhóm mỗi, giả sử 40000 dòng thành một tệp. Nhưng có hai cách của các tập tin "đọc".

1) Cái đầu tiên là đọc toàn bộ tệp cùng một lúc và đưa nó vào danh sách. Nhưng điều này sẽ yêu cầu tải toàn bộ tệp vào bộ nhớ, điều này gây đau đớn cho tệp quá lớn. .

input1=f.readlines()

input1 = commands.getoutput('zcat ' + file).splitlines(True)

input1 = subprocess.Popen(["cat",file],
                              stdout=subprocess.PIPE,bufsize=1)

Chà, sau đó tôi chỉ có thể dễ dàng nhóm 40000 dòng thành một tệp bằng cách: list[40000,80000] or list[80000,120000] hoặc lợi thế của việc sử dụng danh sách là chúng ta có thể dễ dàng trỏ đến các dòng cụ thể.

2) Cách thứ hai là đọc từng dòng; Xử lý dòng khi đọc nó. Những dòng đọc đó sẽ không được lưu trong bộ nhớ. Những ví dụ bao gồm:

f=gzip.open(file)
for line in f: blablabla...

hoặc

for line in fileinput.FileInput(fileName):

Tôi chắc chắn cho gzip.open, F này không phải là một danh sách, mà là một đối tượng tệp. Và dường như chúng ta chỉ có thể xử lý từng dòng; Sau đó, làm thế nào tôi có thể thực hiện công việc "chia tách" này? Làm thế nào tôi có thể trỏ đến các dòng cụ thể của đối tượng tệp?

Cảm ơn

Bài đăng trên blog này cho thấy các cách tiếp cận khác nhau để chia một tệp CSV lớn thành các tệp CSV nhỏ hơn và phác thảo chi phí / lợi ích của các phương pháp khác nhau.

TL;DR

  • Nó nhanh hơn để phân chia tệp CSV với lệnh shell / API hệ thống tập tin Python
  • Gấu trúc / dask là những lựa chọn mạnh mẽ và linh hoạt hơn

Hãy để điều tra các phương pháp khác nhau và xem xét thời gian mất bao lâu để phân chia tệp CSV 2,9 GB với 11,8 triệu hàng dữ liệu.

Tách với vỏ

Bạn có thể chia CSV trên hệ thống tập tin cục bộ của mình bằng lệnh shell.

FILENAME=nyc-parking-tickets/Parking_Violations_Issued_-_Fiscal_Year_2015.csv

split -b 10000000 $FILENAME tmp/split_csv_shell/file

Điều này chỉ mất 4 giây để chạy. Mỗi đầu ra tệp là 10MB và có khoảng 40.000 hàng dữ liệu.

Cách tiếp cận này có một số nhược điểm khóa:

  • Nó không thể được chạy trên các tệp được lưu trữ trong hệ thống tập tin đám mây như S3
  • Nó bị phá vỡ nếu có dòng mới trong hàng CSV (có thể cho dữ liệu được trích dẫn)
  • Không xử lý hàng tiêu đề

API hệ thống tập tin Python

Bạn cũng có thể sử dụng các đầu đọc / nhà văn của hệ thống tập tin Python để phân chia tệp CSV.

chunk_size = 40000

def write_chunk(part, lines):
    with open('../tmp/split_csv_python/data_part_'+ str(part) +'.csv', 'w') as f_out:
        f_out.write(header)
        f_out.writelines(lines)

with open("../nyc-parking-tickets/Parking_Violations_Issued_-_Fiscal_Year_2015.csv", "r") as f:
    count = 0
    header = f.readline()
    lines = []
    for line in f:
        count += 1
        lines.append(line)
        if count % chunk_size == 0:
            write_chunk(count // chunk_size, lines)
            lines = []
    # write remainder
    if len(lines) > 0:
        write_chunk((count // chunk_size) + 1, lines)

Điều này mất 9,6 giây để chạy và xuất đúng ra hàng tiêu đề trong mỗi tệp CSV phân chia, không giống như cách tiếp cận tập lệnh shell.

Nó sẽ dễ dàng hơn để điều chỉnh tập lệnh này để chạy trên các tệp được lưu trữ trong một kho lưu trữ đối tượng đám mây so với tập lệnh shell.

Hãy cùng nhìn vào một số cách tiếp cận chậm hơn một chút, nhưng linh hoạt hơn.

Gấu trúc

Tại đây, cách đọc trong các phần của tệp CSV vào các khung dữ liệu gấu trúc và sau đó viết ra mỗi khung dữ liệu.

source_path = "../nyc-parking-tickets/Parking_Violations_Issued_-_Fiscal_Year_2015.csv"

for i,chunk in enumerate(pd.read_csv(source_path, chunksize=40000, dtype=dtypes)):
    chunk.to_csv('../tmp/split_csv_pandas/chunk{}.csv'.format(i), index=False)

Cách tiếp cận này ghi 296 tệp, mỗi tệp có khoảng 40.000 hàng dữ liệu. & NBSP; Phải mất 160 giây để thực hiện.

Cách tiếp cận gấu trúc linh hoạt hơn các phương pháp hệ thống tập tin Python vì nó cho phép bạn xử lý dữ liệu trước khi viết. & NBSP; Bạn có thể dễ dàng cập nhật tập lệnh để thêm các cột, lọc hàng hoặc ghi dữ liệu lên các định dạng tệp khác nhau.

Việc điều khiển đầu ra là có thể với cách tiếp cận shell và khó khăn / dễ bị lỗi với cách tiếp cận hệ thống tập tin Python.

Bỏ qua

Tại đây, cách đọc tệp CSV vào một datas DataFrame trong các khối 10 MB và ghi dữ liệu dưới dạng tệp CSV 287.

ddf = dd.read_csv(source_path, blocksize=10000000, dtype=dtypes)

ddf.to_csv("../tmp/split_csv_dask")

Tập lệnh DASK chạy trong 172 giây.

Đối với tính toán cụ thể này, thời gian chạy DASK gần bằng với thời gian chạy của gấu trúc. & NBSP; Biểu đồ tác vụ DASK xây dựng các hướng dẫn để xử lý tệp dữ liệu tương tự như tập lệnh gấu trúc, do đó, chúng có ý nghĩa là chúng mất cùng lúc để thực thi.

DASK cho phép một số xử lý dữ liệu trung gian có thể với tập lệnh gấu trúc, như sắp xếp toàn bộ bộ dữ liệu. & NBSP; Kịch bản gấu trúc chỉ đọc trong các phần dữ liệu, do đó, nó không thể được điều chỉnh để thực hiện các hoạt động xáo trộn trên toàn bộ bộ dữ liệu.

So sánh các phương pháp

Biểu đồ này cho thấy thời gian thực hiện chương trình theo cách tiếp cận.

Hướng dẫn how do you split a large file into smaller files in python? - làm thế nào để bạn chia một tệp lớn thành các tệp nhỏ hơn trong python?

Nếu bạn cần nhanh chóng phân chia một tệp CSV lớn, thì hãy gắn bó với API hệ thống tập tin Python.

Thời gian xử lý thường không phải là yếu tố quan trọng nhất khi phân tách một tệp CSV lớn. & NBSP; Các phân tích dữ liệu cấp sản xuất thường liên quan đến các bước sau:

  • Xác thực dữ liệu và ném ra các hàng rác
  • Gán đúng loại cho mỗi cột
  • Viết dữ liệu vào định dạng tệp tốt để phân tích dữ liệu, như sàn gỗ
  • Nén dữ liệu

Mục tiêu chính khi phân tách một tệp CSV lớn thường là để các phân tích hạ nguồn chạy nhanh hơn và đáng tin cậy hơn. & NBSP; DASK là lựa chọn linh hoạt nhất cho một giải pháp cấp sản xuất.

Bước tiếp theo

Các tệp CSV lớn không tốt cho các phân tích dữ liệu vì chúng có thể được đọc song song. & NBSP; Nhiều tập tin có thể dễ dàng được đọc song song.

Các tệp CSV nói chung bị hạn chế vì chúng không chứa siêu dữ liệu lược đồ, hàng tiêu đề yêu cầu logic xử lý thêm và tính chất dựa trên hàng của tệp không cho phép cắt tỉa cột. & NBSP; Ưu điểm chính của các tệp CSV là chúng có thể đọc được con người, nhưng điều đó không quan trọng nếu bạn xử lý dữ liệu của mình với công cụ xử lý dữ liệu cấp sản xuất, như Python hoặc Dask.

Chia một tệp CSV lớn thành nhiều tệp Parquet (hoặc định dạng tệp tốt khác) là bước đầu tiên tuyệt vời cho đường ống xử lý dữ liệu cấp sản xuất. & NBSP; Dask mất nhiều thời gian hơn một tập lệnh sử dụng API hệ thống tập tin Python, nhưng giúp xây dựng tập lệnh mạnh mẽ hơn. & NBSP; Hiệu suất kéo không có vấn đề gì. & Nbsp; Bạn chỉ cần chia CSV một lần.

Việc xem xét hiệu suất quan trọng hơn là tìm ra cách phân chia tệp theo cách mà sẽ làm cho tất cả các phân tích hạ nguồn của bạn chạy nhanh hơn đáng kể.

Sự đăng ký