Contar quantas linhas existem em um CSV Python?


109

Estou usando o python (Django Framework) para ler um arquivo CSV. Eu retiro apenas 2 linhas deste CSV, como você pode ver. O que venho tentando fazer é armazenar em uma variável o número total de linhas do CSV também.

Como posso obter o número total de linhas?

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

Eu tentei:

len(fileObject)
fileObject.length

1
O que é file_read? É um identificador de arquivo (como em file_read = open("myfile.txt")?
David Robinson

1
file_read = csv.reader (file) pergunta atualizada deve fazer sentido agora.
GrantU

Dê uma olhada nesta pergunta para ideias sobre esse tópico: stackoverflow.com/questions/845058/…
shredding

Respostas:


181

Você precisa contar o número de linhas:

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

O uso sum()com uma expressão geradora é um contador eficiente, evitando armazenar todo o arquivo na memória.

Se você já leu 2 linhas para começar, então você precisa adicionar essas 2 linhas ao seu total; linhas que já foram lidas não estão sendo contadas.


1
Obrigado. Isso funcionará, mas eu tenho que ler as linhas primeiro? Isso parece um pouco de sucesso?
GrantU

4
Você tem que ler as linhas; as linhas não têm um tamanho fixo garantido, então a única maneira de contá-las é lendo todas.
Martijn Pieters

1
@Escachator: em qual plataforma você está? Existem caracteres EOF ( CTRL-Z,\x1A ) no arquivo? Como você abriu o arquivo?
Martijn Pieters

4
@Escachator: seu nome de arquivo tem 53 caracteres então. O leitor pega um objeto iterável ou de arquivo aberto, mas não um nome de arquivo.
Martijn Pieters

6
Observe que se você deseja iterar através do leitor novamente (para processar as linhas, digamos), você precisará redefinir o iterador e recriar o objeto do leitor: file.seek(0)entãofileObject = csv.reader(file)
KevinTydlacka

67

EDITAR 29/10/2018

Obrigado pelos comentários.

Testei vários tipos de código para obter o número de linhas em um arquivo csv em termos de velocidade. O melhor método está abaixo.

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

Aqui está o código testado.

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)

O resultado ficou abaixo.

# 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

Em conclusão, sum(1 for line in f)é o mais rápido. Mas pode não haver diferença significativa de len(f.readlines()).

sample_submission.csv tem 30,2 MB e 31 milhões de caracteres.


Você também deve fechar o arquivo? economizar espaço?
lesolorzanov

1
Por que você prefere sum () ao invés de len () em sua conclusão? Len () é mais rápido em seus resultados!
jorijnsmit

Boa resposta. Uma adição. Embora mais lento, deve-se preferir a for row in csv_reader:solução quando o CSV deve conter novas linhas entre aspas válidas de acordo com rfc4180 . @dixhom qual era o tamanho do arquivo que você testou?
Simon Lang

16

Para fazer isso, você precisa ter um pouco de código como meu exemplo aqui:

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

Eu espero que isso ajude a todos.


1
Gosto desta resposta curta, mas é mais lenta do que a de Martijn Pieters. Para linhas de 10 milhões, %time sum(1 for row in open("df_data_raw.csv")) custa 4,91s enquanto %time len(open("df_data_raw.csv").readlines())custa 14,6s.
Pengju Zhao

10

Várias das sugestões acima contam o número de LINHAS no arquivo csv. Mas alguns arquivos CSV conterão strings entre aspas, que por sua vez contêm caracteres de nova linha. Os arquivos MS CSV geralmente delimitam os registros com \ r \ n, mas usam \ n sozinho nas strings entre aspas.

Para um arquivo como este, contar linhas de texto (conforme delimitado por nova linha) no arquivo dará um resultado muito grande. Portanto, para uma contagem precisa, você precisa usar csv.reader para ler os registros.


6

Primeiro você tem que abrir o arquivo com

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

Em seguida, use o csv.reader para abrir o csv

reader_file = csv.reader(input_file)

Por último, você pode pegar o número de linhas com a instrução 'len'

value = len(list(reader_file))

O código total é este:

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

Lembre-se que se você quiser reutilizar o arquivo csv, você deve fazer um input_file.fseek (0), porque quando você usa uma lista para o reader_file, ele lê todos os arquivos, e o ponteiro no arquivo muda sua posição


6

row_count = sum(1 for line in open(filename)) trabalhou para mim.

Nota: sum(1 for line in csv.reader(filename))parece calcular o comprimento da primeira linha


O primeiro é contar o número de linhas em um arquivo. Se o seu csv tiver quebras de linha nas strings, não mostrará resultados precisos
Danilo Souza Morães

3
numline = len(file_read.readlines())

2
file_readé aparentemente um csv.reader()objeto, portanto, não tem um readlines()método. .readlines()tem que criar uma lista potencialmente grande, que você então descarta novamente.
Martijn Pieters

1
Quando escrevo esta resposta, o tópico não tem informações sobre csv é o objeto leitor de csv.
Alex Troush

3

ao instanciar um objeto csv.reader e iterar o arquivo inteiro, você pode acessar uma variável de instância chamada line_num fornecendo a contagem de linhas:

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

Use "lista" para ajustar um objeto mais funcional.

Você pode então contar, pular, mudar até o desejo do seu coração:

list(fileObject) #list values

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

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

2

Isso funciona para csv e todos os arquivos contendo strings em sistemas operacionais baseados em Unix:

import os

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

Caso o arquivo csv contenha uma linha de campos, você pode deduzir um do numOfLinesacima:

numOfLines = numOfLines - 1

Isso é muito útil para integração em um script Python. +1
Vitalis

2

Você também pode usar um loop for clássico:

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

pode querer tentar algo tão simples como abaixo na linha de comando:

sed -n '$=' filename ou wc -l filename


E se você tiver quebras de linha entre aspas duplas? Isso ainda deve ser considerado parte do mesmo registro. Resposta errada
Danilo Souza Morães

1

Acho que podemos melhorar um pouco a melhor resposta, estou usando:

len = sum(1 for _ in reader)

Além disso, não devemos esquecer que o código pythônico nem sempre tem o melhor desempenho no projeto. Por exemplo: Se pudermos fazer mais operações ao mesmo tempo no mesmo conjunto de dados, é melhor fazer todas no mesmo bucle, em vez de fazer dois ou mais bucles pitônicos.


1
import pandas as pd
data = pd.read_csv('data.csv') 
totalInstances=len(data)

0

experimentar

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

e na saída você pode ver algo como (aa, bb) onde aa é o número de linhas


Apenas tropeçando em coisas, parece que este comentário de forma não é tão ruim e, na verdade, comparativamente muito rápido: stackoverflow.com/questions/15943769/…
dedricF

Oh, mas você vai querer fazer umdata.shape[0]
dedricF
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.