Đếm xem có bao nhiêu dòng trong CSV Python?


108

Tôi đang sử dụng python (Django Framework) để đọc tệp CSV. Tôi chỉ kéo 2 dòng ra khỏi CSV này như bạn có thể thấy. Những gì tôi đã cố gắng làm là lưu trữ trong một biến tổng số hàng mà CSV cũng có.

Làm thế nào tôi có thể nhận được tổng số hàng?

file = object.myfilePath
fileObject = csv.reader(file)
for i in range(2):
    data.append(fileObject.next()) 

Tôi đã thử:

len(fileObject)
fileObject.length

1
file_readgì? Nó có phải là một trình xử lý tệp không (như trong file_read = open("myfile.txt")?
David Robinson

1
file_read = csv.reader (tệp) câu hỏi được cập nhật nên có ý nghĩa ngay bây giờ.
GrantU

Hãy xem câu hỏi này để biết suy nghĩ về chủ đề đó: stackoverflow.com/questions/845058/…
shredding

Câu trả lời:


181

Bạn cần đếm số hàng:

row_count = sum(1 for row in fileObject)  # fileObject is your csv.reader

Sử dụng sum()với biểu thức trình tạo sẽ tạo ra một bộ đếm hiệu quả, tránh lưu toàn bộ tệp trong bộ nhớ.

Nếu bạn đã đọc 2 hàng để bắt đầu, thì bạn cần thêm 2 hàng đó vào tổng số của mình; các hàng đã được đọc sẽ không được tính.


1
Cảm ơn. Ý chí đó hoạt động, nhưng tôi có phải đọc lời thoại trước không? Đó có vẻ là một chút hit?
GrantU

4
Bạn phải đọc lời thoại; các dòng không được đảm bảo là một kích thước cố định, vì vậy cách duy nhất để đếm chúng là đọc tất cả.
Martijn Pieters

1
@Escachator: bạn đang sử dụng nền tảng nào? Có các ký tự EOF ( CTRL-Z,\x1A ) trong tệp không? Bạn đã mở tệp như thế nào?
Martijn Pieters

4
@Escachator: Khi đó tên tệp của bạn có 53 ký tự. Trình đọc lấy một đối tượng tệp có thể lặp lại hoặc đang mở nhưng không nhận một tên tệp.
Martijn Pieters

6
Lưu ý rằng nếu bạn muốn sau đó lặp thông qua việc đọc một lần nữa (để xử lý các hàng, chẳng hạn) sau đó bạn sẽ cần phải thiết lập lại các iterator, và tạo lại đối tượng độc giả: file.seek(0)sau đófileObject = csv.reader(file)
KevinTydlacka

67

2018-10-29 CHỈNH SỬA

Cảm ơn bạn đã cho ý kiến.

Tôi đã thử nghiệm một số loại mã để lấy số dòng trong tệp csv về tốc độ. Phương pháp tốt nhất là dưới đây.

with open(filename) as f:
    sum(1 for line in f)

Đây là mã được kiểm tra.

import timeit
import csv
import pandas as pd

filename = './sample_submission.csv'

def talktime(filename, funcname, func):
    print(f"# {funcname}")
    t = timeit.timeit(f'{funcname}("{filename}")', setup=f'from __main__ import {funcname}', number = 100) / 100
    print('Elapsed time : ', t)
    print('n = ', func(filename))
    print('\n')

def sum1forline(filename):
    with open(filename) as f:
        return sum(1 for line in f)
talktime(filename, 'sum1forline', sum1forline)

def lenopenreadlines(filename):
    with open(filename) as f:
        return len(f.readlines())
talktime(filename, 'lenopenreadlines', lenopenreadlines)

def lenpd(filename):
    return len(pd.read_csv(filename)) + 1
talktime(filename, 'lenpd', lenpd)

def csvreaderfor(filename):
    cnt = 0
    with open(filename) as f:
        cr = csv.reader(f)
        for row in cr:
            cnt += 1
    return cnt
talktime(filename, 'csvreaderfor', csvreaderfor)

def openenum(filename):
    cnt = 0
    with open(filename) as f:
        for i, line in enumerate(f,1):
            cnt += 1
    return cnt
talktime(filename, 'openenum', openenum)

Kết quả là bên dưới.

# sum1forline
Elapsed time :  0.6327946722068599
n =  2528244


# lenopenreadlines
Elapsed time :  0.655304473598555
n =  2528244


# lenpd
Elapsed time :  0.7561274056295324
n =  2528244


# csvreaderfor
Elapsed time :  1.5571560935772661
n =  2528244


# openenum
Elapsed time :  0.773000013928679
n =  2528244

Trong kết luận, sum(1 for line in f)là nhanh nhất. Nhưng có thể không có sự khác biệt đáng kể từ len(f.readlines()).

sample_submission.csv là 30,2MB và có 31 triệu ký tự.


Bạn cũng nên đóng tệp? để tiết kiệm không gian?
lesolorzanov

1
Tại sao bạn thích sum () hơn len () trong kết luận của bạn? Len () nhanh hơn trong kết quả của bạn!
jorijnsmit

Câu trả lời rất hay. Một bổ sung. Mặc dù chậm hơn, người ta nên thích for row in csv_reader:giải pháp hơn khi CSV được cho là chứa các dòng mới được trích dẫn hợp lệ theo rfc4180 . @dixhom tệp bạn đã kiểm tra có dung lượng như thế nào?
Simon Lang

16

Để làm điều đó, bạn cần có một chút mã như ví dụ của tôi ở đây:

file = open("Task1.csv")
numline = len(file.readlines())
print (numline)

Tôi hy vọng điều này sẽ giúp tất cả mọi người.


1
Tôi thích câu trả lời ngắn gọn này, nhưng nó chậm hơn câu trả lời của Martijn Pieters. Đối với 10 triệu dòng, %time sum(1 for row in open("df_data_raw.csv")) chi phí 4,91 giây trong khi %time len(open("df_data_raw.csv").readlines())chi phí 14,6 giây.
Pengju Zhao

10

Một số đề xuất ở trên tính số LINES trong tệp csv. Nhưng một số tệp CSV sẽ chứa các chuỗi được trích dẫn mà bản thân nó chứa các ký tự dòng mới. Tệp MS CSV thường phân tách các bản ghi bằng \ r \ n, nhưng chỉ sử dụng \ n trong các chuỗi được trích dẫn.

Đối với tệp như thế này, việc đếm các dòng văn bản (được phân cách bằng dòng mới) trong tệp sẽ cho kết quả quá lớn. Vì vậy, để có số đếm chính xác, bạn cần sử dụng csv.reader để đọc các bản ghi.


6

Trước tiên, bạn phải mở tệp bằng cách mở

input_file = open("nameOfFile.csv","r+")

Sau đó, sử dụng csv.reader để mở csv

reader_file = csv.reader(input_file)

Cuối cùng, bạn có thể lấy số lượng hàng bằng lệnh 'len'

value = len(list(reader_file))

Mã tổng là sau:

input_file = open("nameOfFile.csv","r+")
reader_file = csv.reader(input_file)
value = len(list(reader_file))

Hãy nhớ rằng nếu bạn muốn sử dụng lại tệp csv, bạn phải tạo input_file.fseek (0), vì khi bạn sử dụng danh sách cho reader_file, nó sẽ đọc tất cả tệp và con trỏ trong tệp sẽ thay đổi vị trí của nó


6

row_count = sum(1 for line in open(filename)) đã làm cho tôi.

Lưu ý: sum(1 for line in csv.reader(filename))dường như tính toán độ dài của dòng đầu tiên


Đầu tiên là đếm số dòng trong một tệp. Nếu csv của bạn có ngắt dòng trong chuỗi, nó sẽ không hiển thị kết quả chính xác
Danilo Souza Moraes

3
numline = len(file_read.readlines())

2
file_readrõ ràng là một csv.reader()đối tượng, vì vậy nó không một readlines()phương pháp. .readlines()phải tạo một danh sách lớn tiềm năng, sau đó bạn lại loại bỏ.
Martijn Pieters

1
Khi tôi viết câu trả lời này, chủ đề không có thông tin về csv là đối tượng người đọc csv.
Alex Troush

3

khi bạn khởi tạo một đối tượng csv.reader và bạn nhập toàn bộ tệp thì bạn có thể truy cập một biến phiên bản có tên là line_num cung cấp số lượng hàng:

import csv
with open('csv_path_file') as f:
    csv_reader = csv.reader(f)
    for row in csv_reader:
        pass
    print(csv_reader.line_num)

2
import csv
count = 0
with open('filename.csv', 'rb') as count_file:
    csv_reader = csv.reader(count_file)
    for row in csv_reader:
        count += 1

print count

2

Sử dụng "danh sách" để phù hợp với một đối tượng hiệu quả hơn.

Sau đó, bạn có thể đếm, bỏ qua, biến đổi cho đến khi trái tim bạn khao khát:

list(fileObject) #list values

len(list(fileObject)) # get length of file lines

list(fileObject)[10:] # skip first 10 lines

2

Bạn cũng có thể sử dụng vòng lặp for cổ điển:

import pandas as pd
df = pd.read_csv('your_file.csv')

count = 0
for i in df['a_column']:
    count = count + 1

print(count)

1

có thể muốn thử một cái gì đó đơn giản như bên dưới trong dòng lệnh:

sed -n '$=' filename hoặc là wc -l filename


Điều gì sẽ xảy ra nếu bạn có dấu ngắt dòng bên trong dấu ngoặc kép? Điều đó vẫn nên được coi là một phần của cùng một hồ sơ. Câu trả lời này là sai
Danilo Souza Moraes

1

Điều này hoạt động cho csv và tất cả các tệp chứa chuỗi trong Hệ điều hành dựa trên Unix:

import os

numOfLines = int(os.popen('wc -l < file.csv').read()[:-1])

Trong trường hợp tệp csv chứa một hàng trường, bạn có thể khấu trừ một hàng numOfLinesở trên:

numOfLines = numOfLines - 1

1

Tôi nghĩ chúng ta có thể cải thiện câu trả lời tốt nhất một chút, tôi đang sử dụng:

len = sum(1 for _ in reader)

Hơn nữa, chúng ta không nên quên mã pythonic không phải lúc nào cũng có hiệu suất tốt nhất trong dự án. Ví dụ: Nếu chúng ta có thể thực hiện nhiều phép toán hơn cùng một lúc trong cùng một tập dữ liệu, tốt hơn hết là bạn nên thực hiện tất cả trong cùng một hạt nhân thay vì tạo ra hai hoặc nhiều hạt nhân pythonic.


0

thử

data = pd.read_csv("data.csv")
data.shape

và trong đầu ra, bạn có thể thấy một cái gì đó như (aa, bb) trong đó aa là số hàng


Chỉ tình cờ gặp một thứ, có vẻ như nhận xét về hình dạng này không quá tệ và thực sự là tương đối nhanh: stackoverflow.com/questions/15943769/…
decricF Ngày

Ồ nhưng bạn sẽ muốn làm mộtdata.shape[0]
decricF Ngày

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.