2014-10-28 15 views
9

Tôi có hàng trăm tệp CSV lớn mà tôi muốn hợp nhất thành một. Tuy nhiên không phải tất cả các tệp CSV đều chứa tất cả các cột. Do đó, tôi cần phải hợp nhất dựa trên tên cột, không phải vị trí cột.Hợp nhất các tệp CSV trong python với các cột khác nhau

Chỉ cần rõ ràng: trong CSV được hợp nhất, giá trị phải trống cho ô đến từ một dòng không có cột của ô đó.

Tôi không thể sử dụng mô-đun gấu trúc vì nó khiến tôi hết bộ nhớ.

Có mô-đun nào có thể thực hiện điều đó hoặc một số mã dễ dàng không?

Trả lời

10

Các lớp csv.DictReadercsv.DictWriter sẽ hoạt động tốt (xem Python docs). Một cái gì đó như thế này:

import csv 
inputs = ["in1.csv", "in2.csv"] # etc 

# First determine the field names from the top line of each input file 
# Comment 1 below 
fieldnames = [] 
for filename in inputs: 
    with open(filename, "r", newline="") as f_in: 
    reader = csv.reader(f_in) 
    headers = next(reader) 
    for h in headers: 
     if h not in fieldnames: 
     fieldnames.append(h) 

# Then copy the data 
with open("out.csv", "w", newline="") as f_out: # Comment 2 below 
    writer = csv.DictWriter(f_out, fieldnames=fieldnames) 
    for filename in inputs: 
    with open(filename, "r", newline="") as f_in: 
     reader = csv.DictReader(f_in) # Uses the field names in this file 
     for line in reader: 
     # Comment 3 below 
     writer.writerow(line) 

Comments với phần trên:

  1. Bạn cần phải xác định tất cả các tên trường có thể trước để DictWriter, vì vậy bạn cần phải lặp qua tất cả CSV của bạn tập tin hai lần: một lần để tìm tất cả các tiêu đề và một lần để đọc dữ liệu. Không có giải pháp tốt hơn, bởi vì tất cả các tiêu đề cần phải được biết trước khi DictWriter có thể viết dòng đầu tiên. Phần này sẽ hiệu quả hơn khi sử dụng các bộ thay vì danh sách (toán tử in trên danh sách tương đối chậm), nhưng nó sẽ không tạo ra nhiều khác biệt cho vài trăm tiêu đề. Bộ cũng sẽ mất thứ tự xác định danh sách - các cột của bạn sẽ xuất hiện theo thứ tự khác mỗi khi bạn chạy mã.
  2. Mã trên là dành cho Python 3, nơi những điều kỳ lạ xảy ra trong mô-đun CSV mà không cần newline="". Loại bỏ điều này cho Python 2.
  3. Tại thời điểm này, line là một dict có tên trường là khóa và dữ liệu cột dưới dạng giá trị. Bạn có thể chỉ định phải làm gì với giá trị trống hoặc không xác định trong các nhà thầu DictReaderDictWriter.

Phương pháp này không được hết bộ nhớ vì không bao giờ có toàn bộ tệp được tải cùng một lúc.

+0

Cảm ơn! Điều này hoạt động nhưng tất cả các tệp CSV đầu vào đều có tiêu đề và chúng được lặp lại trong tệp được hợp nhất với mã ở trên. Làm cách nào để thả dòng này cho mỗi tệp ngoại trừ tệp đầu tiên? –

+0

Thực ra các cột của tôi không được căn chỉnh trong tài liệu đã được hợp nhất. Đang cố gắng tìm ra lý do. –

+0

223 cột trong out.csv của tôi, nhưng độ dài tên trường của tôi là 368 ...? –

1

Đối với những người dùng chúng tôi sử dụng 2.7, điều này sẽ thêm một dòng cấp bổ sung giữa các bản ghi trong "out.csv". Để giải quyết vấn đề này, chỉ cần thay đổi chế độ tập tin từ "w" thành "wb".

+0

Điều gì sẽ thêm nguồn cấp dữ liệu bổ sung? Câu trả lời được chấp nhận? Nếu vậy, điều này thực sự phải là một bình luận về câu trả lời được chấp nhận và không phải là một câu trả lời riêng biệt. – akousmata

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