¿Cuenta cuántas líneas hay en un CSV Python?

109

Estoy usando Python (Django Framework) para leer un archivo CSV. Saco solo 2 líneas de este CSV como puede ver. Lo que he estado tratando de hacer es almacenar en una variable el número total de filas del CSV también.

¿Cómo puedo obtener el número total de filas?

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

Yo he tratado:

len(fileObject)
fileObject.length
GrantU
fuente
1
¿Qué es file_read? ¿Es un identificador de archivo (como en file_read = open("myfile.txt")?
David Robinson
1
file_read = csv.reader (file) La pregunta actualizada debería tener sentido ahora.
GrantU
Eche un vistazo a esta pregunta para obtener ideas sobre ese tema: stackoverflow.com/questions/845058/…
shredding

Respuestas:

181

Necesitas contar el número de filas:

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

El uso sum()con una expresión generadora lo convierte en un contador eficiente, evitando almacenar todo el archivo en la memoria.

Si ya leyó 2 filas para empezar, entonces necesita agregar esas 2 filas a su total; las filas que ya se han leído no se cuentan.

Martijn Pieters
fuente
1
Gracias. Eso funcionará, pero ¿tengo que leer las líneas primero? ¿Eso parece un éxito?
GrantU
4
Usted tiene que leer las líneas; No se garantiza que las líneas tengan un tamaño fijo, por lo que la única forma de contarlas es leerlas todas.
Martijn Pieters
1
@Escachator: ¿en qué plataforma estás? ¿Hay caracteres EOF ( CTRL-Z,\x1A ) en el archivo? ¿Cómo abriste el archivo?
Martijn Pieters
4
@Escachator: Su nombre de archivo tiene 53 caracteres entonces. El lector toma un objeto de archivo iterable o abierto, pero no un nombre de archivo.
Martijn Pieters
6
Tenga en cuenta que si desea volver a recorrer el lector en iteración (para procesar las filas, por ejemplo), deberá restablecer el iterador y volver a crear el objeto del lector: file.seek(0)entoncesfileObject = csv.reader(file)
KevinTydlacka
67

2018-10-29 EDITAR

Gracias por los comentarios.

Probé varios tipos de código para obtener la cantidad de líneas en un archivo csv en términos de velocidad. El mejor método es el siguiente.

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

Aquí está el código probado.

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)

El resultado estaba por debajo.

# 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

En conclusión, sum(1 for line in f)es el más rápido. Pero puede que no haya una diferencia significativa entre len(f.readlines()).

sample_submission.csv tiene 30,2 MB y 31 millones de caracteres.

dixhom
fuente
¿Debería cerrar también el archivo? para ahorrar espacio?
lesolorzanov
1
¿Por qué prefiere sum () sobre len () en su conclusión? ¡Len () es más rápido en sus resultados!
jorijnsmit
Buena respuesta. Una adición. Aunque más lento, uno debería preferir la for row in csv_reader:solución cuando se supone que el CSV contiene nuevas líneas válidas entre comillas según rfc4180 . @dixhom ¿qué tamaño tenía el archivo que probaste?
Simon Lang
16

Para hacerlo, debe tener un poco de código como mi ejemplo aquí:

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

Espero que esto ayude a todos.

sam collins
fuente
1
Me gusta esta respuesta corta, pero es más lenta que la de Martijn Pieters. Para 10 millones de líneas, %time sum(1 for row in open("df_data_raw.csv")) cuesta 4.91s mientras que %time len(open("df_data_raw.csv").readlines())cuesta 14.6s.
Pengju Zhao
10

Varias de las sugerencias anteriores cuentan el número de LÍNEAS en el archivo csv. Pero algunos archivos CSV contendrán cadenas entre comillas que a su vez contienen caracteres de nueva línea. Los archivos MS CSV generalmente delimitan registros con \ r \ n, pero usan \ n solo dentro de las cadenas entre comillas.

Para un archivo como este, contar líneas de texto (delimitadas por una nueva línea) en el archivo dará un resultado demasiado grande. Entonces, para un recuento preciso, debe usar csv.reader para leer los registros.

Viejo calvo
fuente
6

Primero tienes que abrir el archivo con open

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

Luego use el csv.reader para abrir el csv

reader_file = csv.reader(input_file)

Por último, puede tomar el número de fila con la instrucción 'len'

value = len(list(reader_file))

El código total es este:

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

Recuerde que si desea reutilizar el archivo csv, debe hacer un input_file.fseek (0), porque cuando usa una lista para el reader_file, lee todo el archivo y el puntero en el archivo cambia su posición.

protti
fuente
6

row_count = sum(1 for line in open(filename)) trabajó para mi.

Nota: sum(1 for line in csv.reader(filename))parece calcular la longitud de la primera línea

Mithilesh Gupta
fuente
El primero es contar el número de líneas de un archivo. Si su csv tiene saltos de línea en cadenas, no mostrará resultados precisos
Danilo Souza Morães
3
numline = len(file_read.readlines())
Alex Troush
fuente
2
file_reades al parecer un csv.reader()objeto, por lo que no tiene un readlines()método. .readlines()tiene que crear una lista potencialmente grande, que luego descarta nuevamente.
Martijn Pieters
1
Cuando escribo esta respuesta, el tema no tiene información sobre csv es un objeto lector de csv.
Alex Troush
3

cuando crea una instancia de un objeto csv.reader e incluye todo el archivo, puede acceder a una variable de instancia llamada line_num que proporciona el recuento de filas:

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)
serpiko
fuente
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
akshaynagpal
fuente
2

Utilice "lista" para ajustar un objeto más funcional.

Luego puede contar, saltar, mutar hasta el deseo de su corazón:

list(fileObject) #list values

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

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

Esto funciona para csv y todos los archivos que contienen cadenas en sistemas operativos basados ​​en Unix:

import os

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

En caso de que el archivo csv contenga una fila de campos, puede deducir una de numOfLinesarriba:

numOfLines = numOfLines - 1
Amir
fuente
Esto es muy útil para integrarlo en un script de Python. +1
Vitalis hace
2

También puede utilizar un bucle for clásico:

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

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

print(count)
Arthur Gatignol
fuente
1

Es posible que desee probar algo tan simple como a continuación en la línea de comando:

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

Kevin
fuente
¿Qué pasa si tienes saltos de línea entre comillas dobles? Eso todavía debería considerarse parte del mismo registro. Esta respuesta es incorrecta
Danilo Souza Morães
1

Creo que podemos mejorar un poco la mejor respuesta, estoy usando:

len = sum(1 for _ in reader)

Además, no debemos olvidar que el código pitónico no siempre tiene el mejor rendimiento en el proyecto. Por ejemplo: si podemos hacer más operaciones al mismo tiempo en el mismo conjunto de datos, es mejor hacer todas en el mismo bucle en lugar de hacer dos o más bucles pitónicos.

David Martínez
fuente
0

tratar

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

y en la salida puede ver algo como (aa, bb) donde aa es el número de filas

Rubén Romo
fuente
Simplemente tropezando con cosas, parece que este comentario de forma no es tan malo y en realidad es comparativamente muy rápido: stackoverflow.com/questions/15943769/…
dedricF
Oh, pero querrás hacer undata.shape[0]
dedricF
0
import pandas as pd
data = pd.read_csv('data.csv') 
totalInstances=len(data)
Sadman Sakib
fuente