Compter le nombre d'enregistrements dans un CSV Python?


109

J'utilise python (Django Framework) pour lire un fichier CSV. Je tire juste 2 lignes de ce CSV comme vous pouvez le voir. Ce que j'ai essayé de faire est de stocker dans une variable le nombre total de lignes du CSV également.

Comment puis-je obtenir le nombre total de lignes?

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

J'ai essayé:

len(fileObject)
fileObject.length

1
Qu'est-ce que c'est file_read? Est-ce un descripteur de fichier (comme dans file_read = open("myfile.txt")?
David Robinson

1
file_read = csv.reader (file) question mise à jour devrait avoir un sens maintenant.
GrantU

Jetez un œil à cette question pour en savoir plus sur ce sujet: stackoverflow.com/questions/845058/…
déchiquetage du


La réponse acceptée par @ martjin-pieters est correcte, mais cette question est mal formulée. Dans votre pseudo-code, vous voulez presque certainement compter le nombre de lignes, c'est-à-dire les enregistrements - par opposition à "Compter le nombre de lignes dans un CSV". Parce que certains ensembles de données CSV peuvent inclure des champs qui peuvent être multilignes.
Dan Nguyen il y a

Réponses:


182

Vous devez compter le nombre de lignes:

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

L'utilisation sum()avec une expression de générateur constitue un compteur efficace, évitant de stocker tout le fichier en mémoire.

Si vous avez déjà lu 2 lignes pour commencer, vous devez ajouter ces 2 lignes à votre total; les lignes qui ont déjà été lues ne sont pas comptées.


1
Merci. Cela fonctionnera, mais dois-je d'abord lire les lignes? Cela semble un peu un succès?
GrantU

4
Vous devez lire les lignes; les lignes ne sont pas garanties d'avoir une taille fixe, donc la seule façon de les compter est de les lire toutes.
Martijn Pieters

1
@Escachator: sur quelle plateforme êtes-vous? Y a-t-il des caractères EOF ( CTRL-Z,\x1A ) dans le fichier? Comment avez-vous ouvert le fichier?
Martijn Pieters

4
@Escachator: Votre nom de fichier comporte alors 53 caractères. Le lecteur prend un objet fichier itérable ou ouvert mais pas un nom de fichier.
Martijn Pieters

6
Notez que si vous voulez ensuite parcourir à nouveau le lecteur (pour traiter les lignes, par exemple), vous devrez réinitialiser l'itérateur et recréer l'objet lecteur: file.seek(0)puisfileObject = csv.reader(file)
KevinTydlacka

68

2018-10-29 MODIFIER

Merci pour les commentaires.

J'ai testé plusieurs types de code pour obtenir le nombre de lignes dans un fichier csv en termes de vitesse. La meilleure méthode est ci-dessous.

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

Voici le code testé.

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)

Le résultat était ci-dessous.

# 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 conclusion, sum(1 for line in f)c'est le plus rapide. Mais il pourrait ne pas y avoir de différence significative avec len(f.readlines()).

sample_submission.csv est de 30,2 Mo et contient 31 millions de caractères.


Devez-vous également fermer le fichier? pour économiser de l'espace?
lesolorzanov

1
Pourquoi préférez-vous sum () à len () dans votre conclusion? Len () est plus rapide dans vos résultats!
jorijnsmit le

Bonne réponse. Un ajout. Bien que plus lente, on devrait préférer la for row in csv_reader:solution lorsque le CSV est censé contenir des retours à la ligne valides entre guillemets selon rfc4180 . @dixhom quelle était la taille du fichier que vous avez testé?
Simon Lang

15

Pour ce faire, vous devez avoir un peu de code comme mon exemple ici:

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

J'espère que cela aide tout le monde.


1
J'aime cette réponse courte, mais elle est plus lente que celle de Martijn Pieters. Pour 10 millions de lignes, %time sum(1 for row in open("df_data_raw.csv")) coût 4,91 s et %time len(open("df_data_raw.csv").readlines())14,6 s.
Pengju Zhao

Le titre original de la question ("Compter le nombre de lignes dans un Python CSV") a été formulé de manière confuse / trompeuse, car le questionneur semble vouloir le nombre de lignes / enregistrements. Votre réponse donnerait un nombre incorrect de lignes dans tout ensemble de données contenant des champs avec des caractères de nouvelle ligne
Dan Nguyen il y a

10

Plusieurs des suggestions ci-dessus comptent le nombre de LIGNES dans le fichier csv. Mais certains fichiers CSV contiennent des chaînes entre guillemets qui contiennent elles-mêmes des caractères de nouvelle ligne. Les fichiers MS CSV délimitent généralement les enregistrements avec \ r \ n, mais utilisent \ n seuls dans des chaînes entre guillemets.

Pour un fichier comme celui-ci, compter les lignes de texte (délimitées par une nouvelle ligne) dans le fichier donnera un résultat trop volumineux. Donc, pour un décompte précis, vous devez utiliser csv.reader pour lire les enregistrements.


6

Vous devez d'abord ouvrir le fichier avec open

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

Ensuite, utilisez le csv.reader pour ouvrir le csv

reader_file = csv.reader(input_file)

Enfin, vous pouvez prendre le numéro de ligne avec l'instruction 'len'

value = len(list(reader_file))

Le code total est le suivant:

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

N'oubliez pas que si vous souhaitez réutiliser le fichier csv, vous devez créer un input_file.fseek (0), car lorsque vous utilisez une liste pour le reader_file, il lit tous les fichiers et le pointeur dans le fichier change de position


6

row_count = sum(1 for line in open(filename)) travaillé pour moi.

Remarque: sum(1 for line in csv.reader(filename))semble calculer la longueur de la première ligne


Le premier compte le nombre de lignes dans un fichier. Si votre csv a des sauts de ligne dans les chaînes, il ne montrera pas de résultats précis
Danilo Souza Morães

3
numline = len(file_read.readlines())

2
file_readest apparemment un csv.reader()objet, il n'a donc pas avoir une readlines()méthode. .readlines()doit créer une liste potentiellement volumineuse, que vous rejetez à nouveau.
Martijn Pieters

1
Lorsque j'écris cette réponse, le sujet n'a pas d'informations sur csv est un objet lecteur csv.
Alex Troush

3

lorsque vous instanciez un objet csv.reader et que vous itérez le fichier entier, vous pouvez accéder à une variable d'instance appelée line_num fournissant le nombre de lignes:

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

Utilisez "liste" pour adapter un objet plus pratique.

Vous pouvez alors compter, sauter, muter jusqu'au désir de votre cœur:

list(fileObject) #list values

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

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

2

Cela fonctionne pour csv et tous les fichiers contenant des chaînes dans les systèmes d'exploitation basés sur Unix:

import os

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

Si le fichier csv contient une ligne de champs, vous pouvez en déduire une numOfLinesci-dessus:

numOfLines = numOfLines - 1

C'est très pratique pour l'intégration dans un script python. +1
Vitalis

2

Vous pouvez également utiliser une boucle for classique:

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

peut vouloir essayer quelque chose d'aussi simple que ci-dessous dans la ligne de commande:

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


Que faire si vous avez des sauts de ligne entre guillemets doubles? Cela devrait toujours être considéré comme faisant partie du même dossier. Cette réponse est fausse
Danilo Souza Morães

1

Je pense que nous pouvons améliorer un peu la meilleure réponse, j'utilise:

len = sum(1 for _ in reader)

De plus, il ne faut pas oublier que le code pythonique n'a pas toujours les meilleures performances dans le projet. Par exemple: si nous pouvons faire plus d'opérations en même temps dans le même jeu de données, il vaut mieux faire tout dans le même noyau au lieu de faire deux ou plusieurs bucles pythoniques.


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

-1

essayer

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

et dans la sortie, vous pouvez voir quelque chose comme (aa, bb) où aa est le # de lignes


Trébucher juste sur des choses, il semble que ce commentaire de forme n'est pas si mauvais et en fait relativement très rapide: stackoverflow.com/questions/15943769
...

Oh mais vous voudrez faire undata.shape[0]
dedricF

Mais est-ce relativement rapide par rapport à la réponse de @ martijnpieters, qui utilise un descripteur / itérateur de fichier standard, et ne nécessite pas l'installation et l'importation de la bibliothèque pandas?
Dan Nguyen
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.