นับจำนวนระเบียนใน CSV Python?


110

ฉันใช้ python (Django Framework) เพื่ออ่านไฟล์ CSV ฉันดึงเพียง 2 บรรทัดออกจาก CSV นี้อย่างที่คุณเห็น สิ่งที่ฉันพยายามทำคือเก็บจำนวนแถวทั้งหมดที่ CSV ไว้ในตัวแปร

ฉันจะหาจำนวนแถวทั้งหมดได้อย่างไร

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

ฉันเหนื่อย:

len(fileObject)
fileObject.length

1
คืออะไรfile_read? เป็นที่จับไฟล์file_read = open("myfile.txt")หรือไม่(เช่นเดียวกับใน
David Robinson

1
file_read = csv.reader (ไฟล์) คำถามที่อัปเดตควรมีเหตุผลในตอนนี้
GrantU

ลองดูคำถามนี้สำหรับความคิดในหัวข้อนั้น: stackoverflow.com/questions/845058/…
shredding


1
คำตอบที่ยอมรับโดย @ martjin-pieters นั้นถูกต้อง แต่คำถามนี้ใช้คำไม่ดี ในรหัสเทียมของคุณคุณแทบจะต้องการนับจำนวนแถวเช่นระเบียนซึ่งตรงข้ามกับ "นับจำนวนบรรทัดใน CSV" เนื่องจากชุดข้อมูล CSV บางชุดอาจมีช่องซึ่งอาจเป็นแบบหลายบรรทัด
Dan Nguyen

คำตอบ:


183

คุณต้องนับจำนวนแถว:

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

การใช้sum()กับนิพจน์ของเครื่องกำเนิดไฟฟ้าทำให้ตัวนับมีประสิทธิภาพหลีกเลี่ยงการเก็บไฟล์ทั้งหมดไว้ในหน่วยความจำ

หากคุณอ่าน 2 แถวที่จะเริ่มต้นด้วยแล้วคุณต้องเพิ่ม 2 แถวนั้นในผลรวมของคุณ จะไม่นับแถวที่อ่านไปแล้ว


1
ขอบคุณ. จะได้ผล แต่ฉันต้องอ่านบรรทัดก่อนหรือไม่? ดูเหมือนว่าจะเป็นที่นิยม?
GrantU

4
คุณต้องอ่านบรรทัด ไม่รับประกันว่าเส้นจะมีขนาดคงที่ดังนั้นวิธีเดียวที่จะนับได้คือการอ่านทั้งหมด
Martijn Pieters

1
@Escachator: คุณอยู่บนแพลตฟอร์มอะไร? มีอักขระ EOF ( CTRL-Z\x1A ) ในไฟล์หรือไม่ คุณเปิดไฟล์ได้อย่างไร?
Martijn Pieters

4
@Escachator: ชื่อไฟล์ของคุณมี 53 อักขระแล้ว ผู้อ่านใช้วัตถุที่ทำซ้ำได้หรือเปิดไฟล์ แต่ไม่ใช่ชื่อไฟล์
Martijn Pieters

6
โปรดทราบว่าหากคุณต้องการวนซ้ำผ่านโปรแกรมอ่านอีกครั้ง (เพื่อประมวลผลแถวให้พูด) คุณจะต้องรีเซ็ตตัววนซ้ำและสร้างวัตถุตัวอ่านใหม่: file.seek(0)จากนั้นfileObject = csv.reader(file)
KevinTydlacka

68

2018-10-29 แก้ไข

ขอบคุณสำหรับคอมเม้น

ฉันทดสอบโค้ดหลายประเภทเพื่อรับจำนวนบรรทัดในไฟล์ csv ในแง่ของความเร็ว วิธีการที่ดีที่สุดอยู่ด้านล่าง

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

นี่คือรหัสที่ทดสอบ

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)

ผลลัพธ์อยู่ด้านล่าง

# 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

สรุปsum(1 for line in f)ได้เร็วที่สุด len(f.readlines())แต่อาจไม่ได้มีความแตกต่างอย่างมีนัยสำคัญจาก

sample_submission.csv คือ 30.2MB และมีอักขระ 31 ล้านตัว


คุณควรปิดไฟล์ด้วยหรือไม่? เพื่อประหยัดพื้นที่?
lesolorzanov

1
ทำไมคุณถึงชอบ sum () มากกว่า len () ในข้อสรุปของคุณ? Len () เร็วกว่าในผลลัพธ์ของคุณ!
jorijnsmit

คำตอบที่ดี หนึ่งนอกจากนี้ แม้ว่าจะช้ากว่าหนึ่งควรชอบfor row in csv_reader:วิธีการแก้ปัญหาเมื่อ CSV ควรจะมีการขึ้นบรรทัดใหม่ยกมาถูกต้องตามrfc4180 @dixhom ไฟล์ที่คุณทดสอบมีขนาดใหญ่แค่ไหน?
Simon Lang

16

ในการทำคุณต้องมีโค้ดเล็กน้อยเช่นตัวอย่างของฉันที่นี่:

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

ฉันหวังว่านี่จะช่วยทุกคนได้


1
ฉันชอบคำตอบสั้น ๆ นี้ แต่ช้ากว่าของ Martijn Pieters สำหรับสาย 10M %time sum(1 for row in open("df_data_raw.csv")) ราคา 4.91 วินาทีในขณะที่%time len(open("df_data_raw.csv").readlines())ราคา 14.6 วินาที
Pengju Zhao

ชื่อเดิมของคำถาม ("นับจำนวนบรรทัดใน CSV Python") มีคำที่สับสน / ทำให้เข้าใจผิดเนื่องจากผู้ถามดูเหมือนจะต้องการจำนวนแถว / ระเบียน คำตอบของคุณจะให้จำนวนแถวที่ไม่ถูกต้องในชุดข้อมูลใด ๆ ที่มีช่องที่มีอักขระขึ้นบรรทัดใหม่
Dan Nguyen

10

คำแนะนำข้างต้นหลายข้อจะนับจำนวน LINES ในไฟล์ csv แต่ไฟล์ CSV บางไฟล์จะมีสตริงที่ยกมาซึ่งมีอักขระขึ้นบรรทัดใหม่ โดยทั่วไปไฟล์ MS CSV จะคั่นระเบียนด้วย \ r \ n แต่ใช้ \ n เพียงอย่างเดียวภายในสตริงที่ยกมา

สำหรับไฟล์ลักษณะนี้การนับบรรทัดข้อความ (เนื่องจากคั่นด้วยขึ้นบรรทัดใหม่) ในไฟล์จะให้ผลลัพธ์ที่ใหญ่เกินไป ดังนั้นสำหรับการนับที่แม่นยำคุณต้องใช้ csv.reader เพื่ออ่านบันทึก


6

ก่อนอื่นคุณต้องเปิดไฟล์โดยเปิด

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

จากนั้นใช้ csv.reader เพื่อเปิด csv

reader_file = csv.reader(input_file)

ในที่สุดคุณสามารถใช้จำนวนแถวด้วยคำสั่ง 'len'

value = len(list(reader_file))

รหัสรวมคือ:

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

โปรดจำไว้ว่าหากคุณต้องการใช้ไฟล์ csv ซ้ำคุณต้องสร้าง input_file.fseek (0) เนื่องจากเมื่อคุณใช้รายการสำหรับ reader_file ไฟล์จะอ่านไฟล์ทั้งหมดและตัวชี้ในไฟล์จะเปลี่ยนตำแหน่ง


6

row_count = sum(1 for line in open(filename)) ทำงานให้ฉัน

หมายเหตุ: sum(1 for line in csv.reader(filename))ดูเหมือนจะคำนวณความยาวของบรรทัดแรก


อันแรกคือการนับจำนวนบรรทัดในไฟล์ หาก csv ของคุณมีการแบ่งบรรทัดในสตริงจะไม่แสดงผลลัพธ์ที่ถูกต้อง
Danilo Souza Morães

3
numline = len(file_read.readlines())

2
file_readคือเห็นได้ชัดcsv.reader()วัตถุจึงไม่ได้มีreadlines()วิธี .readlines()ต้องสร้างรายการที่มีขนาดใหญ่ซึ่งคุณจะทิ้งอีกครั้ง
Martijn Pieters

1
เมื่อฉันเขียนคำตอบนี้หัวข้อไม่มีข้อมูลเกี่ยวกับ csv คือวัตถุอ่าน csv
Alex Troush

3

เมื่อคุณสร้างอินสแตนซ์อ็อบเจ็กต์ csv.reader และคุณ iter ทั้งไฟล์คุณจะสามารถเข้าถึงตัวแปรอินสแตนซ์ที่เรียกว่า line_num โดยให้จำนวนแถว:

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

ใช้ "รายการ" เพื่อให้พอดีกับวัตถุที่ใช้งานได้มากขึ้น

จากนั้นคุณสามารถนับข้ามกลายพันธุ์ตามความปรารถนาของหัวใจ:

list(fileObject) #list values

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

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

2

สิ่งนี้ใช้ได้กับ csv และไฟล์ทั้งหมดที่มีสตริงในระบบปฏิบัติการที่ใช้ Unix:

import os

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

ในกรณีที่ไฟล์ csv มีแถวเขตข้อมูลคุณสามารถหักออกจากnumOfLinesด้านบน:

numOfLines = numOfLines - 1

สิ่งนี้มีประโยชน์มากสำหรับการรวมเข้ากับสคริปต์ python +1
Vitalis

2

คุณยังสามารถใช้คลาสสิกสำหรับการวนซ้ำ:

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

อาจต้องการลองทำสิ่งง่ายๆดังต่อไปนี้ในบรรทัดคำสั่ง:

sed -n '$=' filename หรือ wc -l filename


จะเกิดอะไรขึ้นถ้าคุณมีตัวแบ่งบรรทัดภายในเครื่องหมายคำพูดคู่? สิ่งนั้นควรถือเป็นส่วนหนึ่งของบันทึกเดียวกัน คำตอบนี้ไม่ถูกต้อง
Danilo Souza Morães

1

ฉันคิดว่าเราสามารถปรับปรุงคำตอบที่ดีที่สุดได้เล็กน้อยฉันใช้:

len = sum(1 for _ in reader)

ยิ่งไปกว่านั้นเราไม่ควรลืมรหัส pythonic ไม่ได้มีประสิทธิภาพดีที่สุดในโครงการเสมอไป ตัวอย่างเช่นหากเราสามารถดำเนินการได้มากขึ้นในเวลาเดียวกันในชุดข้อมูลเดียวกันจะเป็นการดีกว่าที่จะทำทั้งหมดใน bucle เดียวกันแทนที่จะสร้าง pythonic bucles สองตัวขึ้นไป



0

ลอง

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

และในผลลัพธ์คุณจะเห็นบางอย่างเช่น (aa, bb) โดยที่ aa คือ # ของแถว


แค่สะดุดกับสิ่งของต่างๆดูเหมือนว่าความคิดเห็นรูปร่างนี้ไม่ได้แย่มากนักและเปรียบเทียบได้เร็วมากจริงๆ: stackoverflow.com/questions/15943769/…
dedricF

แต่คุณจะต้องทำ adata.shape[0]
dedricF

แต่มันค่อนข้างเร็วเมื่อเทียบกับคำตอบของ @ martijnpieters ซึ่งใช้ตัวจัดการไฟล์มาตรฐาน / ตัววนซ้ำและไม่จำเป็นต้องติดตั้งและนำเข้าไลบรารีแพนด้า?
Dan Nguyen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.