Contare quanti record ci sono in un CSV Python?


108

Sto usando python (Django Framework) per leggere un file CSV. Tiro fuori solo 2 righe da questo CSV come puoi vedere. Quello che ho cercato di fare è memorizzare in una variabile anche il numero totale di righe del CSV.

Come posso ottenere il numero totale di righe?

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

Ho provato:

len(fileObject)
fileObject.length

1
Che cos'è file_read? È un file handle (come in file_read = open("myfile.txt")?
David Robinson,

1
file_read = csv.reader (file) la domanda aggiornata dovrebbe avere senso ora.
GrantU

Dai un'occhiata a questa domanda per pensieri su questo argomento: stackoverflow.com/questions/845058/…
shredding


La risposta accettata da @ martjin-pieters è corretta, ma questa domanda è formulata male. Nel tuo pseudocodice, quasi certamente vuoi contare il numero di righe, ovvero i record , invece di "Conta quante righe ci sono in un CSV". Perché alcuni set di dati CSV possono includere campi che possono essere multilinea.
Dan Nguyen

Risposte:


181

Devi contare il numero di righe:

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

L'utilizzo sum()con un'espressione generatore crea un contatore efficiente, evitando di archiviare l'intero file in memoria.

Se hai già letto 2 righe per iniziare, devi aggiungere quelle 2 righe al tuo totale; le righe che sono già state lette non vengono conteggiate.


1
Grazie. Funzionerà, ma devo prima leggere le righe? Sembra un po 'un successo?
GrantU

4
È necessario leggere le righe; non è garantito che le righe abbiano una dimensione fissa, quindi l'unico modo per contarle è leggerle tutte.
Martijn Pieters

1
@Escachator: su quale piattaforma sei? Sono presenti caratteri EOF ( CTRL-Z,\x1A ) nel file? Come hai aperto il file?
Martijn Pieters

4
@Escachator: il nome del file ha quindi 53 caratteri. Il lettore accetta un oggetto file iterabile o aperto ma non un nome file.
Martijn Pieters

6
Nota che se vuoi quindi iterare di nuovo attraverso il lettore (per elaborare le righe, diciamo), dovrai reimpostare l'iteratore e ricreare l'oggetto lettore: file.seek(0)quindifileObject = csv.reader(file)
KevinTydlacka

67

2018-10-29 EDIT

Grazie per i commenti.

Ho testato diversi tipi di codice per ottenere il numero di righe in un file csv in termini di velocità. Il metodo migliore è di seguito.

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

Ecco il codice testato.

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)

Il risultato era sotto.

# 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

In conclusione, sum(1 for line in f)è più veloce. Ma potrebbe non esserci una differenza significativa da len(f.readlines()).

sample_submission.csv è 30,2 MB e contiene 31 milioni di caratteri.


Dovresti anche chiudere il file? risparmiare spazio?
lesolorzanov

1
Perché preferisci sum () rispetto a len () nella tua conclusione? Len () è più veloce nei risultati!
jorijnsmit

Bella risposta. Un'aggiunta. Sebbene più lento, si dovrebbe preferire la for row in csv_reader:soluzione quando si suppone che il CSV contenga nuove righe quotate valide secondo rfc4180 . @dixhom quanto era grande il file che hai testato?
Simon Lang

15

Per farlo devi avere un po 'di codice come il mio esempio qui:

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

Spero che questo possa aiutare tutti.


1
Mi piace questa risposta breve, ma è più lenta di quella di Martijn Pieters. Per 10 milioni di linee, %time sum(1 for row in open("df_data_raw.csv")) costa 4,91 secondi mentre %time len(open("df_data_raw.csv").readlines())costa 14,6 secondi.
Pengju Zhao

Il titolo originale della domanda ("Conta quante righe ci sono in un CSV Python") era formulato in modo confuso / fuorviante, poiché l'interrogante sembra volere il numero di righe / record. La tua risposta darebbe un numero sbagliato di righe in qualsiasi set di dati in cui sono presenti campi con caratteri di nuova riga
Dan Nguyen

10

Molti dei suggerimenti precedenti contano il numero di LINEE nel file csv. Ma alcuni file CSV conterranno stringhe tra virgolette che a loro volta contengono caratteri di nuova riga. I file MS CSV di solito delimitano i record con \ r \ n, ma utilizzano \ n da soli all'interno di stringhe tra virgolette.

Per un file come questo, il conteggio delle righe di testo (delimitate da una nuova riga) nel file darà un risultato troppo grande. Quindi per un conteggio accurato è necessario utilizzare csv.reader per leggere i record.


6

Per prima cosa devi aprire il file con open

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

Quindi usa il csv.reader per aprire il csv

reader_file = csv.reader(input_file)

Alla fine, puoi prendere il numero di righe con l'istruzione 'len'

value = len(list(reader_file))

Il codice totale è questo:

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

Ricorda che se vuoi riutilizzare il file csv, devi creare un input_file.fseek (0), perché quando usi una lista per il reader_file, legge tutti i file e il puntatore nel file cambia la sua posizione


6

row_count = sum(1 for line in open(filename)) ha funzionato per me.

Nota: sum(1 for line in csv.reader(filename))sembra calcolare la lunghezza della prima riga


Il primo è contare il numero di righe in un file. Se il tuo CSV ha interruzioni di riga nelle stringhe, non mostrerà risultati accurati
Danilo Souza Morães

3
numline = len(file_read.readlines())

2
file_readè apparentemente un csv.reader()oggetto, quindi non ha un readlines()metodo. .readlines()deve creare un elenco potenzialmente grande, che poi scarterai di nuovo.
Martijn Pieters

1
Quando scrivo questa risposta, l'argomento non ha informazioni su csv è un oggetto lettore csv.
Alex Troush

3

quando istanziate un oggetto csv.reader e iterate l'intero file, potete accedere a una variabile di istanza chiamata line_num fornendo il conteggio delle righe:

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

Usa "list" per adattare un oggetto più funzionale.

Puoi quindi contare, saltare, mutare fino al desiderio del tuo cuore:

list(fileObject) #list values

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

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

2

Funziona per csv e tutti i file contenenti stringhe nei sistemi operativi basati su Unix:

import os

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

Nel caso in cui il file csv contenga una riga di campi, puoi dedurne una numOfLinesdall'alto:

numOfLines = numOfLines - 1

Questo è molto utile per l'integrazione in uno script Python. +1
Vitalis

2

Puoi anche usare un classico ciclo for:

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

potrebbe voler provare qualcosa di semplice come di seguito nella riga di comando:

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


Cosa succede se hai interruzioni di riga tra virgolette doppie? Questo dovrebbe comunque essere considerato parte dello stesso record. Questa risposta è sbagliata
Danilo Souza Morães

1

Penso che possiamo migliorare un po 'la risposta migliore, sto usando:

len = sum(1 for _ in reader)

Inoltre, non dobbiamo dimenticare che il codice pitonico non sempre ha le migliori prestazioni nel progetto. Ad esempio: se possiamo fare più operazioni contemporaneamente nello stesso set di dati, è meglio fare tutte nella stessa bucle invece fare due o più bucle pitoniche.


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

-1

provare

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

e nell'output puoi vedere qualcosa come (aa, bb) dove aa è il numero di righe


Basta imbattersi in cose, sembra questo commento forma non è così male e in realtà relativamente molto veloce: stackoverflow.com/questions/15943769/...
dedricF

Oh, ma vorrai fare undata.shape[0]
dedricF

Ma è relativamente veloce rispetto alla risposta di @ martijnpieters, che utilizza un handle / iteratore di file standard e non richiede l'installazione e l'importazione della libreria pandas?
Dan Nguyen
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.