Python 找到csv中的行数而不加载完整内容的最佳方法

Python 找到csv中的行数而不加载完整内容的最佳方法,python,pandas,csv,Python,Pandas,Csv,在过去几天的工作中,我一直在处理大量4-5 Gb的csv文件,因此我知道通过读/写,我在pandas方法的基础上编写了两个包装器函数,它们取得了多大进展。这一切似乎都运行得很好,有点开销,但方便性压倒了大多数问题 同时,在读取csv时,为了让进度条显示正确的百分比,我需要提前知道行数,因为这决定了将有多少块。我提出的最简单的解决方案是,在开始加载其余列并获取其大小之前,只加载csv的第0列。但当您有数百万行大小的文件时,这确实需要一些时间 此外,读取单个列的时间占总时间的比例过高:在csv中读取

在过去几天的工作中,我一直在处理大量4-5 Gb的csv文件,因此我知道通过读/写,我在pandas方法的基础上编写了两个包装器函数,它们取得了多大进展。这一切似乎都运行得很好,有点开销,但方便性压倒了大多数问题

同时,在读取csv时,为了让进度条显示正确的百分比,我需要提前知道行数,因为这决定了将有多少块。我提出的最简单的解决方案是,在开始加载其余列并获取其大小之前,只加载csv的第0列。但当您有数百万行大小的文件时,这确实需要一些时间

此外,读取单个列的时间占总时间的比例过高:在csv中读取包含125列和数百万行的单个列需要约24秒,读取整个文件需要63秒

这是我用来读取CSV的函数:

def read_csv_与_progressbar(文件名:str,
chunksize:int=50000)->pd.DataFrame:
length=pd.read\u csv(文件名,usecols=[0])
长度=长度.值.形状[0]
总计=长度//块大小
chunk_list=[]
chunks=pd.read\u csv(文件名,chunksize=chunksize)
将tqdm(total=total,file=sys.stdout)作为pbar:
对于块中的块:
chunk\u list.append(chunk)
pbar.set_说明('读取源csv文件')
pbar.update(1)
df=pd.concat([i代表块列表中的i],轴=0)
返回df

有没有比使用我的有缺陷的方法更快地获得csv中的行数的方法?

假设csv文件中没有带引号的字符串(其中有换行符)或其他诡计,一个准确的(但有黑客攻击性的)解决方案是甚至不解析文件,而只是简单地计算文件中的换行数:

chunk = 1024*1024   # Process 1 MB at a time.
f = np.memmap("test.csv")
num_newlines = sum(np.sum(f[i:i+chunk] == ord('\n'))
                   for i in range(0, len(f), chunk))
del f

你看过这篇文章了吗?刚刚测试了提议的解决方案。使用pandas加载单个列要比使用
file.open()
计算行快,例如,使用pandas加载24秒,使用替代方法加载36秒。诚实的真实答案是,您应该切换到比CSV更结构化的文件格式。不管怎样,任何算法都必须分析完整的5GB以准确回答您的查询。@orlp,不幸的是,这是不可能的。另一方面,我处理的许多文件的格式大致相同,有125列,大多数数据都是浮动的。我想快速而肮脏的解决方案是根据文件大小估计行数。谢谢!这是一个非常好的解决方案!使用pandas的速度是使用pandas的两倍,使用my files.open()的速度是使用pandas的三倍。@pavel如果您想以牺牲准确性为代价获得更高的速度,您可以在整个文件中半随机采样(例如)50MB的数据,并将其线性外推到整个文件中。