Python tách regex csv

Tôi đề nghị bạn tận dụng các khả năng được cung cấp bởi gấu trúc. Dưới đây là các chức năng bạn có thể sử dụng để làm điều đó

Nội dung chính Hiển thị

  • Tách với vỏ
  • API system file Python
  • Gấu trúc
  • So sánh các phương pháp
  • Bước tiếp theo

def csv_count_rows(file):
    """
    Counts the number of rows in a file.
    :param file: path to the file.
    :return: number of lines in the designated file.
    """
    with open(file) as f:
        nb_lines = sum(1 for line in f)
    return nb_lines


def split_csv(file, sep=",", output_path=".", nrows=None, chunksize=None, low_memory=True, usecols=None):
    """
    Split a csv into several files.
    :param file: path to the original csv.
    :param sep: View pandas.read_csv doc.
    :param output_path: path in which to output the resulting parts of the splitting.
    :param nrows: Number of rows to split the original csv by, also view pandas.read_csv doc.
    :param chunksize: View pandas.read_csv doc.
    :param low_memory: View pandas.read_csv doc.
    :param usecols: View pandas.read_csv doc.
    """
    nb_of_rows = csv_count_rows(file)

    # Parsing file elements : Path, name, extension, etc...
    # file_path = "/".join(file.split("/")[0:-1])
    file_name = file.split("/")[-1]
    # file_ext = file_name.split(".")[-1]
    file_name_trunk = file_name.split(".")[0]
    split_files_name_trunk = file_name_trunk + "_part_"

    # Number of chunks to partition the original file into
    nb_of_chunks = math.ceil(nb_of_rows / nrows)
    if nrows:
        log_debug_process_start = f"The file '{file_name}' contains {nb_of_rows} ROWS. " \
            f"\nIt will be split into {nb_of_chunks} chunks of a max number of rows : {nrows}." \
            f"\nThe resulting files will be output in '{output_path}' as '{split_files_name_trunk}0 to {nb_of_chunks - 1}'"
        logging.debug(log_debug_process_start)

    for i in range(nb_of_chunks):
        # Number of rows to skip is determined by (the number of the chunk being processed) multiplied by (the nrows parameter).
        rows_to_skip = range(1, i * nrows) if i else None
        output_file = f"{output_path}/{split_files_name_trunk}{i}.csv"

        log_debug_chunk_processing = f"Processing chunk {i} of the file '{file_name}'"
        logging.debug(log_debug_chunk_processing)

        # Fetching the original csv file and handling it with skiprows and nrows to process its data
        df_chunk = pd.read_csv(filepath_or_buffer=file, sep=sep, nrows=nrows, skiprows=rows_to_skip,
                               chunksize=chunksize, low_memory=low_memory, usecols=usecols)
        df_chunk.to_csv(path_or_buf=output_file, sep=sep)

        log_info_file_output = f"Chunk {i} of file '{file_name}' created in '{output_file}'"
        logging.info(log_info_file_output)

And after that in the record copy or Jupyter of you that you set

# This is how you initiate logging in the most basic way.
logging.basicConfig(level=logging.DEBUG)
file = {#Path to your file}
split_csv(file,sep=";" ,output_path={#Path where you'd like to output it},nrows = 4000000, low_memory = False)

P. S. 1. Tôi đặt nrows = 4000000 vì khi đó là sở thích cá nhân. You can change the number if you want

P. S. 2. Tôi đã sử dụng nhật ký thư viện để hiển thị tin nhắn. Khi nào sẽ áp dụng một chức năng như vậy trên các tệp hiện có trên một máy chủ từ xa, bạn thực sự muốn tránh 'trong đơn giản' và kết hợp các khả năng ghi nhật ký. You can instead logging.info or logging.debug by print

P. S. 3. Tất nhiên, bạn cần thay thế các phần ____10 của mã bằng các tham số của riêng bạn

Bài đăng trên blog này cho thấy các cách tiếp cận khác nhau để chia sẻ 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 bằng lệnh shell / API hệ thống tệp Python
  • Gấu trúc / dask là những lựa chọn mạnh mẽ và linh hoạt hơn

Vui lòng điều khiển 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ỏ

You can share CSV on local file system of your own by shell command

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 tệp đầu ra là 10 MB 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ể chạy trên các tệp được lưu trữ trong hệ thống đám mây 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ý được tiêu đề hàng

API system file Python

Bạn cũng có thể sử dụng đầu đọc / nhà văn của hệ thống tệp 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 hàng tiêu đề trong mỗi tệp CSV được chia, không giống như cách phân tích tiếp theo shell tệp lệnh

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 tin đã đượ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 cận cảnh 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 đó ghi ra từng 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.  

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.  

The first control control is could with the way next close shell and hard/dễ bị lỗi with the way next next system file Python

Remove

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

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

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

Lệnh DASK chạy trong 172 giây

Đối với công cụ tính toán này, thời gian chạy DASK gần bằng với thời gian chạy của khung kiến ​​trúc.  

DASK cho phép một số xử lý dữ liệu trung gian có thể phù hợp với cấu trúc tập lệnh, như sắp xếp toàn 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

Python tách regex csv

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

Thời gian xử lý thông thường không phải là yếu tố quan trọng nhất khi phân tách tệp CSV lớn.  

  • 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 nguồn phân tích giảm chạy nhanh hơn và đáng tin cậy hơn.  

Bước tiếp theo

Tệp CSV không tốt cho các phân tích dữ liệu vì chúng không thể đọc được bài hát.  

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ý bổ sung 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.  

Chia một tệp CSV 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.   .   .  

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ể