2012-02-12 30 views
20

Tôi có một loạt tệp CSV được nén mà tôi muốn mở để kiểm tra bằng trình đọc CSV được tích hợp sẵn của Python. Tôi muốn làm điều này mà không cần phải giải nén chúng vào đĩa một cách thủ công. Tôi đoán tôi muốn bằng cách nào đó có được một luồng dữ liệu chưa nén, và chuyển nó vào trình đọc CSV. Điều này có thể thực hiện được bằng Python không?Sử dụng csvreader đối với tệp được nén trong Python

+0

Ngoài các giải pháp Python bản địa ở đây, 'gói pandas' có [' read_csv'] (https : //pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html) trình đọc có hỗ trợ gzip – smci

Trả lời

26

Sử dụng các mô-đun gzip:

with gzip.open(filename) as f: 
    reader = csv.reader(f) 
    #... 
+0

Nếu 'filename = 'tzaman.csv'' thì tệp của nó sẽ tạo tệp' tzaman.csv'. lưu trữ tệp và chứa một tệp 'tzaman.csv' khác thực sự là tệp csv. nếu chúng ta đặt tên nó là 'abc.zip' thì nó sẽ thêm' abc.zip' là một zip và chứa một tệp 'abc.zip' thực sự là một csv. Phải làm gì? – Clayton

+0

Nó không nén tập tin? – Clayton

+1

Nó không tạo ra một kho lưu trữ. Gzip chỉ là một máy nén luồng. Tên tệp phải được gọi là 'tzsman.csv.gz' để giúp xác định loại tệp. Ngoài ra, thư viện gzip không hỗ trợ câu lệnh with trong Python 2.6.8. – Doug

6

một giải pháp hoàn chỉnh hơn:

import csv, gzip 
class GZipCSVReader: 
    def __init__(self, filename): 
     self.gzfile = gzip.open(filename) 
     self.reader = csv.DictReader(self.gzfile) 
    def next(self): 
     return self.reader.next() 
    def close(self): 
     self.gzfile.close() 
    def __iter__(self): 
     return self.reader.__iter__() 

bây giờ bạn có thể sử dụng nó như thế này:

r = GZipCSVReader('my.csv') 
for map in r: 
    for k,v in map: 
     print k,v 
r.close() 
+0

Gọn gàng. Neater nếu bạn có thể thêm '__enter _/__ exit __()' phương thức quản lý ngữ cảnh để nó có thể được sử dụng với câu lệnh 'with'. – smci

19

Tôi đã thử các phiên bản trên để viết và đọc và nó không hoạt động trong Python 3.3 do lỗi "byte". Tuy nhiên, sau khi một số thử nghiệm và lỗi tôi có thể nhận được những điều sau đây để làm việc. Có lẽ nó cũng giúp những người khác:

import csv 
import gzip 
import io 


with gzip.open("test.gz", "w") as file: 
    writer = csv.writer(io.TextIOWrapper(file, newline="", write_through=True)) 
    writer.writerow([1, 2, 3]) 
    writer.writerow([4, 5, 6]) 

with gzip.open("test.gz", "r") as file: 
    reader = csv.reader(io.TextIOWrapper(file, newline="")) 
    print(list(reader)) 

Như amohr cho thấy, các công trình sau đây cũng như:

import gzip, csv 

with gzip.open("test.gz", "wt", newline="") as file: 
    writer = csv.writer(file) 
    writer.writerow([1, 2, 3]) 
    writer.writerow([4, 5, 6]) 

with gzip.open("test.gz", "rt", newline="") as file: 
    reader = csv.reader(file) 
    print(list(reader)) 
+0

@Gerenuk nó hoạt động như một sự quyến rũ! – ZuLu

+0

Giải pháp này cũng hoạt động với 'io.BufferedReader' có thể nhanh hơn theo một số [điểm chuẩn] (http://ebnj.net/pythongzipbenchmarks/). Chỉ cần bọc 'gzip.open' bằng' io.BufferedReader' làm cho nó 'với io.BufferedReader (gzip.open ("test.gz",' r ')) dưới dạng tệp: ' –

+2

bạn có thể bỏ qua TextIOWrapper/BufferedReader nếu bạn sử dụng gzip.open (chế độ = 'rt' – amohr

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